Triangular PV question

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
maksimKorzh
Posts: 771
Joined: Sat Sep 08, 2018 5:37 pm
Location: Ukraine
Full name: Maksim Korzh

Re: Triangular PV question

Post by maksimKorzh »

Harald wrote: Sun Sep 13, 2020 10:24 pm I am not even sure if I did it right.
I can't exactly understand the reason behind

Code: Select all

if (in_pv && ply < last_pv_length)
    last_pv_move = pv_moves[0][ply];
and I still can't understand how switching in_pv (follow_pv) is switched,
I mean I see all the places it has been changed in the search but can't understand WHY.
My idea is, just reuse the ply = 0 row from the diagonal pv table from a previous iteration
while it is still valid at the very beginning of the current iteration. Another idea would be
to copy that pv line to an extra last_pv array. But I think between the begin of the current iteration
and the initialisation of the current pv_move[ply][ply] = no_move there is just a small gap in time and code
where we can pick the pv_move from the last iteration and store it in local last_pv_move
for later use in this search function body. We just must be sure that we are at the leftmost
branch of our search tree (in_pv == true) and that a long enough pv sequence from the last
iteration exists (ply < last_pv_length). After we exausted the last pv sequence we can
no longer access it and have to use other move order techniques. The easiest way to switch off
the pv method is to just switch it off (in_pv = false) each time we come back from
any search tree branch without any further test. Even if we switch it off millions of times.

And by the way, instead of making the pv move before the move generation you can also
use only your normal move list and just give the last_pv_move a better sort score (+100000).
Just figured out how to apply PV move sorting as implemented in TSCP:

Code: Select all

global
int follow_pv = 0;
score_pv = 0;


in iterative deepening every iteration:
follow_pv = 1;

----

moves *move_list[1];
generate_moves(move_list);

if (follow_pv) sort_pv(move_list);

sort_moves(move_list)

// loop over moves
// make/take/etc...
===================

// called for every move from sort_moves
int score_move(moves *move_list)
{
   // score pv
   if (score_pv)
   {
       if (pv_table[0][ply] == move)
       {
          score_pv = 0;
          return 20000; // score PV move
       }
   }

   ....
}

void sort_pv(moves *move_list)
{
	follow_pv = 0;
	for(int i = 0; i < move_list->count; ++i)
		if (pv_table[0][ply] == move_list->moves[i]) {
			follow_pv = 1;
			score_pv = 1;
			//printf("PV move: "); print_move(move_list->moves[i]); printf("\n");
			return;
		}
}
Well at least now I'm 100% sure it WORKS just like in TSCP.
Also the number of saved nodes is better compared to the version I used here:
http://talkchess.com/forum3/viewtopic.php?f=7&t=75097

Anyway, video is coming soon, so at least I will be able to demonstrate the implementation.
Probably when I implement zobrist hashing it can be improved to link pv move with position hash key like implemented in VICE.
Time will show. At least TSCP's implementation with my minor modifications is the EASIEST and most straightforward.
At least we can safely use it even if not clearly understand all the details.