Error in getting the pv using triangular pv line

Discussion of chess software programming and technical issues.

Moderator: Ras

shahil4242
Posts: 30
Joined: Thu Sep 28, 2017 5:20 pm

Error in getting the pv using triangular pv line

Post by shahil4242 »

Is there any error in pv storing pv line and retrieving pv line in my code.

During first 5 moves it is getting correctly but after that it is not getting properly.

This is my search_code.

Could you help me to fix this.

Thank you.

Code: Select all

#include "defs.h"

U64 nodes;
U64 qnodes;

int killer[2][32];
int history[256][256];
int pv[32][32];
int pv_index[32];

int score_piece_value[6] = {
    100, 300, 350, 500, 900, 1200
};

int get_move_score(int move)
{
    int score = 0;
    int from  = move & 255, to = ((move >> 8) & 255), flag = (move >> 16);
    int promote = get_promote_piece(flag);

    if(flag & MOVE_FLAG_CAPTURE)
    {
        score += score_piece_value[pos->piece[to]];
        score -= score_piece_value[pos->piece[from]];
        score += 40000;
    }
    
    if(flag & MOVE_FLAG_EP_CAPTURE)
        score += 55000;
    
    if(promote != -1)
        score += 20000 + score_piece_value[promote];
    
    if(killer[0][pos->ply] == move)
        score += 70000;
    else if(killer[1][pos->ply] == move)
        score += 60000;
    else
        score += history[from][to];
    
    return score;
}

void clear_search(void)
{
    int ply, from, to, index;
    
    for(ply = 0; ply <= 31; ply++)
        killer[0][ply] = killer[1][ply] = 0;
    
    for(from = 0; from <= 255; from++)
    {
        for(to = 0; to <= 255; to++)
            history[from][to] = 0;
    }
    
    for(index = 0; index <= 31; index++)
    {
        pv_index[index] = 0;
        for(ply = 0; ply <= 31; ply++)
            pv[ply][index] = 0;
    }
}

void init_search(void)
{
    nodes  = 0;
    qnodes = 0;
    pos->ply = 0;
    
    clear_search();
    // pv_index[0] = 0;
    
    search_info->quit    = 0;
    search_info->stopped = 0;
}

int is_three_fold_or_fifty(void)
{
    int index;
    
    for(index = 0; index < pos->hply; index++)
    {
        if(pos->key == pos->history_list[index].key)
            return 1;
    }
    
    if(pos->fifty >= 100)
        return 1;
    
    return 0;
}

int qsearch(int alpha, int beta)
{

    if((qnodes & 2047) == 0)
        check_up();
    
    qnodes += 1;
    
    if(is_three_fold_or_fifty() == 1)
        return 0;
    
    int score = eval();
	
    if(pos->ply >= 31)
        return score;

    pv_index[pos->ply] = pos->ply;
    
	if(score >= beta)
        return beta;
    
	if(score > alpha)
		alpha = score;
    

    int index, j, move, legal = 0;
	score = -30000;
    
    type_move_list move_list[1];
    
    movegen_capture(move_list);
    sort_move_list(move_list);
    for(index = 0;index < move_list->count; index++)
    {
        move = move_list->moves[index].move;
        if(!make_move(move))
            continue;

		legal++;
		score = -qsearch(-beta, -alpha);        
        unmake_move();

        if(search_info->stopped == 1)
            return 0;
        
        if(score > alpha)
        {
            if(score >= beta)
                return beta;
            alpha = score;
            pv[pos->ply][pos->ply] = move;
            for(j = pos->ply + 1; j < pv_index[pos->ply + 1]; j++)
                pv[pos->ply][j] = pv[pos->ply + 1][j];
            pv_index[pos->ply] = pv_index[pos->ply + 1];
        }                
    }    
    
    return alpha;
}

int search(int alpha, int beta, int depth)
{    
    if(depth <= 0)
        return qsearch(alpha, beta);
    
    pv_index[pos->ply] = pos->ply;
    
    if((nodes & 2047) == 0)
        check_up();
    
    nodes += 1;

    if(is_three_fold_or_fifty() == 1 && pos->ply != 0)
        return 0;

    int score = eval(), best_score, best_move = 0;
	
    if(pos->ply >= 31)
        return score;    

    int flag_check = in_check(pos->side);

    if(flag_check == 1)
        depth += 1;

    score = probe_hash_entry(alpha, beta, depth, &best_move);
	if(score != HASH_FLAG_NONE)
        return score;
    
    int index, j, move, legal = 0, old_alpha = alpha;
    int from, to, flag;
	best_score = score = -30000;
    
    type_move_list move_list[1];
    
    movegen(move_list);
    
    if(pv[0][0] != 0)
    {
        for(index = 0;index < move_list->count; index++)
        {
            move = move_list->moves[index].move;
            if(pv[0][0] == move)
            {
                move_list->moves[index].score = 999999;
                break;
            }
        }
    }
    
    if(best_move != 0)
    {
        for(index = 0;index < move_list->count; index++)
        {
            move = move_list->moves[index].move;
            if(best_move == move)
            {
                move_list->moves[index].score = 888888;
                break;
            }
        }
    }
    
    sort_move_list(move_list);
    for(index = 0;index < move_list->count; index++)
    {
        move = move_list->moves[index].move;
        from  = move & 255, to = ((move >> 8) & 255), flag = (move >> 16);
        if(!make_move(move))
            continue;

		legal++;
		score = -search(-beta, -alpha, depth - 1);
        unmake_move();

        if(search_info->stopped == 1)
            return 0;
        
        if(score > best_score)
        {
            best_score = score;
            best_move = move;
            if(score > alpha)
            {
                if(score >= beta)
                {
					if(!(flag & MOVE_FLAG_CAPTURE))
                    {
						killer[1][pos->ply] = killer[0][pos->ply];
						killer[0][pos->ply] = move;
                    }
                    
                    store_hash_entry(score, depth, HASH_FLAG_BETA, best_move);
                    
                    return beta;
                }
                if(!(flag & MOVE_FLAG_CAPTURE))
                    history[from][to] += depth;
                alpha = score;
                
                pv[pos->ply][pos->ply] = move;
                for(j = pos->ply + 1; j < pv_index[pos->ply + 1]; j++)
                    pv[pos->ply][j] = pv[pos->ply + 1][j];
                pv_index[pos->ply] = pv_index[pos->ply + 1];
            }
        }
    }

    if(legal == 0)
    {
        if(flag_check)
            return -30000 + pos->ply;
        else
            return 0;
    }
 

    if(alpha != old_alpha)
        store_hash_entry(best_score, depth, HASH_FLAG_EXACT, best_move);
    else
        store_hash_entry(alpha, depth, HASH_FLAG_ALPHA, best_move);
    
    return alpha;
}

void think(void)
{
    int depth = 0, best_move = 0, best_score = -30000, j;
    
    init_search();
        
    for(depth = 1; depth <= search_info->depth; depth++)
    {

		best_score = search(-30000, 30000, depth);

        if(search_info->stopped == 1)
            break;
        
        printf("info score cp %d depth %d nodes %lld qnodes %lld pv",
            best_score, depth, nodes, qnodes);
        for (j = 0; j < pv_index[0]; j++)
        {
            ASSERT(pv[0][j] != 0);
            printf(" %s", move_string(pv[0][j]));
        }
        printf("\n");
            
    }
    ASSERT(pv[0][0] != 0);
    if(pv[0][0])
        printf("bestmove %s\n", move_string(pv[0][0]));
}

Here is the log.

Code: Select all

2023-06-13 06:08:07.975**----------New game---2023-06-13 06:08:07,975 Tue -------------
2023-06-13 06:08:12.211*1*Start calc, move no: 0
2023-06-13 06:08:12.211-->1:ucinewgame
2023-06-13 06:08:12.211-->1:isready
2023-06-13 06:08:12.211<--1:ucinewgame
2023-06-13 06:08:12.211<--1:readyok
2023-06-13 06:08:12.221-->1:position startpos
2023-06-13 06:08:12.221-->1:go depth 4
2023-06-13 06:08:12.221<--1:info score cp 32 depth 1 nodes 1 qnodes 20 pv b1c3
2023-06-13 06:08:12.221<--1:info score cp 0 depth 2 nodes 22 qnodes 67 pv b1c3 b8c6
2023-06-13 06:08:12.232<--1:info score cp 32 depth 3 nodes 82 qnodes 549 pv b1c3 b8c6 g1f3
2023-06-13 06:08:12.232<--1:info score cp 0 depth 4 nodes 606 qnodes 1673 pv b1c3 b8c6 g1f3 g8f6
2023-06-13 06:08:12.232<--1:bestmove b1c3
2023-06-13 06:08:12.232*1*Found move:Nb1-c3
2023-06-13 06:08:12.472*2*Start calc, move no: 1
2023-06-13 06:08:12.472-->2:ucinewgame
2023-06-13 06:08:12.472-->2:isready
2023-06-13 06:08:12.472<--2:ucinewgame
2023-06-13 06:08:12.472<--2:readyok
2023-06-13 06:08:12.482-->2:position startpos moves b1c3
2023-06-13 06:08:12.482-->2:go depth 4
2023-06-13 06:08:12.482<--2:info score cp 0 depth 1 nodes 1 qnodes 20 pv b8c6
2023-06-13 06:08:12.482<--2:info score cp -32 depth 2 nodes 22 qnodes 68 pv b8c6 g1f3
2023-06-13 06:08:12.482<--2:info score cp 0 depth 3 nodes 84 qnodes 509 pv b8c6 g1f3 g8f6
2023-06-13 06:08:12.482<--2:info score cp -15 depth 4 nodes 571 qnodes 1500 pv b8c6 g1f3 g8f6
2023-06-13 06:08:12.482<--2:bestmove b8c6
2023-06-13 06:08:12.482*2*Found move:Nb8-c6
2023-06-13 06:08:12.842*1*Start calc, move no: 2
2023-06-13 06:08:12.842-->1:position startpos moves b1c3 b8c6
2023-06-13 06:08:12.842-->1:go depth 4
2023-06-13 06:08:12.862<--1:info score cp 32 depth 1 nodes 1 qnodes 22 pv g1f3
2023-06-13 06:08:12.862<--1:info score cp 0 depth 2 nodes 24 qnodes 77 pv g1f3 g8f6
2023-06-13 06:08:12.872<--1:info score cp 15 depth 3 nodes 90 qnodes 645 pv g1f3 g8f6 d2d4
2023-06-13 06:08:12.872<--1:info score cp 0 depth 4 nodes 735 qnodes 3494 pv g1f3 g8f6 d2d4 d7d5
2023-06-13 06:08:12.872<--1:bestmove g1f3
2023-06-13 06:08:12.872*1*Found move:Ng1-f3
2023-06-13 06:08:13.113*2*Start calc, move no: 3
2023-06-13 06:08:13.113-->2:position startpos moves b1c3 b8c6 g1f3
2023-06-13 06:08:13.113-->2:go depth 4
2023-06-13 06:08:13.123<--2:info score cp -15 depth 1 nodes 1 qnodes 0 pv
2023-06-13 06:08:13.123<--2:info score cp -15 depth 2 nodes 2 qnodes 0 pv
2023-06-13 06:08:13.123<--2:info score cp 0 depth 3 nodes 122 qnodes 862 pv g8f6 d2d4 d7d5
2023-06-13 06:08:13.133<--2:info score cp -16 depth 4 nodes 739 qnodes 4457 pv g8f6 d2d4 d7d5
2023-06-13 06:08:13.133<--2:bestmove g8f6
2023-06-13 06:08:13.133*2*Found move:Ng8-f6
2023-06-13 06:08:13.413*1*Start calc, move no: 4
2023-06-13 06:08:13.413-->1:position startpos moves b1c3 b8c6 g1f3 g8f6
2023-06-13 06:08:13.413-->1:go depth 4
2023-06-13 06:08:13.433<--1:info score cp 15 depth 1 nodes 1 qnodes 26 pv d2d4
2023-06-13 06:08:13.433<--1:info score cp 0 depth 2 nodes 26 qnodes 130 pv d2d4 d7d5
2023-06-13 06:08:13.433<--1:info score cp 16 depth 3 nodes 98 qnodes 3597 pv d2d4 d7d5 c1f4
2023-06-13 06:08:13.443<--1:info score cp 0 depth 4 nodes 821 qnodes 15980 pv d2d4 d7d5 c1f4 c8g4
2023-06-13 06:08:13.443<--1:bestmove d2d4
2023-06-13 06:08:13.443*1*Found move:d2-d4
2023-06-13 06:08:13.674*2*Start calc, move no: 5
2023-06-13 06:08:13.674-->2:position startpos moves b1c3 b8c6 g1f3 g8f6 d2d4
2023-06-13 06:08:13.674-->2:go depth 4
2023-06-13 06:08:13.694<--2:info score cp -16 depth 1 nodes 1 qnodes 0 pv
2023-06-13 06:08:13.694<--2:info score cp -16 depth 2 nodes 2 qnodes 0 pv
2023-06-13 06:08:13.704<--2:info score cp 0 depth 3 nodes 199 qnodes 2535 pv d7d5 c1f4 c8f5
2023-06-13 06:08:13.704<--2:info score cp -12 depth 4 nodes 1076 qnodes 11469 pv d7d5 d1d3 e7e6
2023-06-13 06:08:13.704<--2:bestmove d7d5
2023-06-13 06:08:13.704*2*Found move:d7-d5
2023-06-13 06:08:13.944*1*Start calc, move no: 6
2023-06-13 06:08:13.944-->1:position startpos moves b1c3 b8c6 g1f3 g8f6 d2d4 d7d5
2023-06-13 06:08:13.944-->1:go depth 4
2023-06-13 06:08:13.984<--1:info score cp 16 depth 1 nodes 1 qnodes 33 pv c1f4
2023-06-13 06:08:13.984<--1:info score cp 0 depth 2 nodes 32 qnodes 381 pv c1f4 c8g4
2023-06-13 06:08:13.994<--1:info score cp 12 depth 3 nodes 163 qnodes 4551 pv d1d3 a7a6
2023-06-13 06:08:13.994<--1:info score cp 6 depth 4 nodes 1393 qnodes 41572 pv d1d3 c8e6 c1f4 d8d7
2023-06-13 06:08:13.994<--1:bestmove d1d3
2023-06-13 06:08:13.994*1*Found move:Qd1-d3
2023-06-13 06:08:14.244*2*Start calc, move no: 7
2023-06-13 06:08:14.244-->2:position startpos moves b1c3 b8c6 g1f3 g8f6 d2d4 d7d5 d1d3
2023-06-13 06:08:14.244-->2:go depth 4
2023-06-13 06:08:14.304<--2:info score cp -12 depth 1 nodes 1 qnodes 0 pv
2023-06-13 06:08:14.304<--2:info score cp -12 depth 2 nodes 2 qnodes 0 pv
2023-06-13 06:08:14.315<--2:info score cp 0 depth 3 nodes 197 qnodes 4552 pv d8d6 c3b5 d6b4
2023-06-13 06:08:14.315<--2:info score cp -12 depth 4 nodes 1230 qnodes 47316 pv e7e6
2023-06-13 06:08:14.315<--2:bestmove e7e6
2023-06-13 06:08:14.315*2*Found move:e7-e6
2023-06-13 06:08:14.555*1*Start calc, move no: 8
2023-06-13 06:08:14.555-->1:position startpos moves b1c3 b8c6 g1f3 g8f6 d2d4 d7d5 d1d3 e7e6
2023-06-13 06:08:14.555-->1:go depth 4
2023-06-13 06:08:14.595<--1:info score cp 8 depth 1 nodes 1 qnodes 0 pv
2023-06-13 06:08:14.595<--1:info score cp 8 depth 2 nodes 2 qnodes 0 pv
2023-06-13 06:08:14.595<--1:info score cp 16 depth 3 nodes 212 qnodes 4554 pv c1f4 f8b4 a1d1
2023-06-13 06:08:14.595<--1:info score cp 8 depth 4 nodes 1664 qnodes 29250 pv c1f4 f8b4 f3e5 f6e4
2023-06-13 06:08:14.605<--1:bestmove c1f4
2023-06-13 06:08:14.605*1*Found move:Bc1-f4
2023-06-13 06:08:14.845*2*Start calc, move no: 9
2023-06-13 06:08:14.845-->2:position startpos moves b1c3 b8c6 g1f3 g8f6 d2d4 d7d5 d1d3 e7e6 c1f4
2023-06-13 06:08:14.845-->2:go depth 4
2023-06-13 06:08:14.845<--2:info score cp -11 depth 1 nodes 1 qnodes 0 pv
2023-06-13 06:08:14.845<--2:info score cp -11 depth 2 nodes 2 qnodes 0 pv
2023-06-13 06:08:14.855<--2:info score cp -11 depth 3 nodes 3 qnodes 0 pv
2023-06-13 06:08:14.855<--2:info score cp -11 depth 4 nodes 4 qnodes 0 pv
2023-06-13 06:08:14.855<--2:pv[0][0] != 0 - failed on Jun 13 2023 at 06:06:34 in file search.c at line 303
2023-06-13 06:08:21.505-->2:stop
smatovic
Posts: 3220
Joined: Wed Mar 10, 2010 10:18 pm
Location: Hamburg, Germany
Full name: Srdja Matovic

Re: Error in getting the pv using triangular pv line

Post by smatovic »

I never implemented Triangular PV as on CPW:
https://www.chessprogramming.org/Triangular_PV-Table
many programmers have abandoned PV-Table and reveal the PV from the transposition table.
but switched directly to TT Hash-Table with get_pv function:
https://github.com/smatovic/ZetaDva/blo ... dva.c#L681

...you will need a TT Hash Table anyways:
https://www.chessprogramming.org/Transposition_Table
https://www.chessprogramming.org/Hash_Table

--
Srdja