Moderator: Andres Valverde
Josu? Forte wrote:Hi Ron,
Thanks for the link.
I will send another email to Nalimov.
Yes, you are right about Matheus homepage. It is not working since one month ago. I will choose another host to get the page back.
Best regards,
Josu?
Josu? Forte wrote:Hi Vincent,
If I am not wrong you are the author of a strong engine called diep. Congrats for your creation!
Well, answering your question "why not make your own EGTBs like many programmers have done by now?".
I would say for the same reason so many skilled programmers have done this way up to now. To just mention one of them, that I most respect, Robert Hyatt. As Bob said one time in a forum discussion "why reinvent the whell?".
But you are right. I will not spam Nalimov a second time about this subject. Instead, a couple of weeks ago I started working on a bitbase code which seems to be superior to EGTB in terms of size and speed.
A coulple of EGTB files (kpk.nbw and kpk.nbb), with size of about 80 Kb each file, can be now converted to a mere compressed single file of 3600 bytes. And I can use it without permission.
Nevertheless, I respect very much Nalimov's work.
With my best regards,
Josu?.
can imagine that for probing during search WDL is usually good enough to know if you should go for the conversion or not. For actually playing an end-game it seems not sufficient to ensure progress, though: in (say) KbbKn evrything where you don't sacrifice a Bishop will remain won, and the bit-base data is basically useless because there are easier ways to check if you lost a Bishop.... But then probing a DTM at game level directly from disk is not too slow.
H.G.Muller wrote:But how do you handle positions that can be won, but only in more than 50 moves? Do you store them as wins or as draws? In the former case it might fumble wins because it unnecessarily converts to a 'slow win' where 'fast wins' could have been forced, in the other case you might miss a swindle victory against opponents that did not have the TB.
/* EGTB Probing code. */
#ifdef EGTB
if (egtb_limit >= total_pieces &&
((status[move_number].white_castle + status[move_number].black_castle) == 0) &&
(!status[move_number].enpassant_sq)) {
if (EgtbProbe(&score)) {
int mate_distance = 0;
/* Mate scores have to be adjusted because here "score" represents mate in N moves
from the root. We must store "score" as mate in N moves from this position. */
alpha = score;
if (alpha) {
if (alpha > 0)
score = alpha + ply;
else
score = alpha - ply;
mate_distance = MATE_VALUE - abs(score);
}
/* If 50 moves rule reached then position is a draw. */
if ((status[move_number].fifty_moves_rule + mate_distance) > 100) {
pv_length[ply] = 0;
return(0);
}
/* Record EGTB score in hashtables -> "always" and "depth" elements. */
if (!follow_pv) {
hash_entry->always.flag.bound = hash_entry->depth.flag.bound = EGTB_SCORE;
hash_entry->always.move = hash_entry->depth.move = NO_MOVE;
hash_entry->always.hashkey = hash_entry->depth.hashkey = hashkey;
hash_entry->always.score = hash_entry->depth.score = score;
hash_entry->always.depth_remaining = hash_entry->depth.depth_remaining = MAX_DEPTH;
if (age != hash_entry->depth.flag.age) {
hashtable_write++;
hash_entry->depth.flag.age = (unsigned char)age;
}
pv_length[ply] = 0;
return(alpha);
}
}
}
#endif /* EGTB */
H.G.Muller wrote:
But how do you handle positions that can be won, but only in more than 50 moves? Do you store them as wins or as draws? In the former case it might fumble wins because it unnecessarily converts to a 'slow win' where 'fast wins' could have been forced, in the other case you might miss a swindle victory against opponents that did not have the TB.
Does this simply occur so infrequently that you don't need to worry about it? Many EGTBs of course have no 'slow wins' at all.
bob wrote:That code won't work and has a _serious_ bug...
say we are in an ending like KBB vs KN, and we have played 40 moves toward a mate in 70. And your test says "draw" since the mate distance is beyond the 50 move rule counter. Unfortunately, between here and where the 50 move rule counter hits 100, we are going to make a capture (winning the knight) which resets the counter. But you have already said "draw" because you can't see the counter getting reset.
That's not worth the effort since it tries to hide a problem but introduces a potentially bigger problem...
#ifdef EGTB
if (egtb_limit >= total_pieces &&
((status[move_number].white_castle + status[move_number].black_castle) == 0) &&
(!status[move_number].enpassant_sq)) {
if (EgtbProbe(&score)) {
int mate_distance = 0;
// Mate scores have to be adjusted because here "score" represents mate in N moves
// from the root. We must store "score" as mate in N moves from this position.
alpha = score;
if (alpha) {
if (alpha > 0)
score = alpha + ply;
else
score = alpha - ply;
mate_distance = MATE_VALUE - abs(score);
}
/* If 50 moves rule reached then position is a draw. */
if ((status[move_number].fifty_moves_rule + mate_distance) > 100) {
Retrieve_EGTB_Path(&egtb_line);
if (no_capture or pawn_push in egtb_line before 50_moves_rule is reached) {
pv_length[ply] = 0;
return(0);
}
}
// Record EGTB score in hashtables -> "always" and "depth" elements.
if (!follow_pv) {
hash_entry->always.flag.bound = hash_entry->depth.flag.bound = EGTB_SCORE;
hash_entry->always.move = hash_entry->depth.move = NO_MOVE;
hash_entry->always.hashkey = hash_entry->depth.hashkey = hashkey;
hash_entry->always.score = hash_entry->depth.score = score;
hash_entry->always.depth_remaining = hash_entry->depth.depth_remaining = MAX_DEPTH;
if (age != hash_entry->depth.flag.age) {
hashtable_write++;
hash_entry->depth.flag.age = (unsigned char)age;
}
pv_length[ply] = 0;
return(alpha);
}
}
}
#endif /* EGTB */
Josu? Forte wrote:bob wrote:That code won't work and has a _serious_ bug...
say we are in an ending like KBB vs KN, and we have played 40 moves toward a mate in 70. And your test says "draw" since the mate distance is beyond the 50 move rule counter. Unfortunately, between here and where the 50 move rule counter hits 100, we are going to make a capture (winning the knight) which resets the counter. But you have already said "draw" because you can't see the counter getting reset.
That's not worth the effort since it tries to hide a problem but introduces a potentially bigger problem...
Hi Bob,
You are simply 100% right!
I did not think about that.
But you have just given me a way to by-pass the problem.
If you get a mate score from EGTB you can get the mate_path that lead to that score, right?
bob wrote:That code won't work and has a _serious_ bug...
say we are in an ending like KBB vs KN, and we have played 40 moves toward a mate in 70. And your test says "draw" since the mate distance is beyond the 50 move rule counter. Unfortunately, between here and where the 50 move rule counter hits 100, we are going to make a capture (winning the knight) which resets the counter. But you have already said "draw" because you can't see the counter getting reset.
That's not worth the effort since it tries to hide a problem but introduces a potentially bigger problem...
The problem is that the mate path is not the correct path.
It is possible that the mate path based on the tablebases lead to draw by the 50 move rule but the winner can get longer mate when the capture happens earlier.
The only practical solution to solve the problem is simply to generate tablebases based on the 50 move rule.
Josu? Forte wrote:bob wrote:That code won't work and has a _serious_ bug...
say we are in an ending like KBB vs KN, and we have played 40 moves toward a mate in 70. And your test says "draw" since the mate distance is beyond the 50 move rule counter. Unfortunately, between here and where the 50 move rule counter hits 100, we are going to make a capture (winning the knight) which resets the counter. But you have already said "draw" because you can't see the counter getting reset.
That's not worth the effort since it tries to hide a problem but introduces a potentially bigger problem...
Hi Bob,
You are simply 100% right!
I did not think about that.
But you have just given me a way to by-pass the problem.
If you get a mate score from EGTB you can get the mate_path that lead to that score, right?
So, instead of returning a draw score, as stated in my previous code, we simply need to go through the mate_path and verify if there is a capture or pawn_push before 50_moves_rule is reached.
See may code below.
This way we can definitely solve the problem. (at least this problem. )
Thanks for you comments.
My best regards,
Josu?.
- Code: Select all
#ifdef EGTB
if (egtb_limit >= total_pieces &&
((status[move_number].white_castle + status[move_number].black_castle) == 0) &&
(!status[move_number].enpassant_sq)) {
if (EgtbProbe(&score)) {
int mate_distance = 0;
// Mate scores have to be adjusted because here "score" represents mate in N moves
// from the root. We must store "score" as mate in N moves from this position.
alpha = score;
if (alpha) {
if (alpha > 0)
score = alpha + ply;
else
score = alpha - ply;
mate_distance = MATE_VALUE - abs(score);
}
/* If 50 moves rule reached then position is a draw. */
if ((status[move_number].fifty_moves_rule + mate_distance) > 100) {
Retrieve_EGTB_Path(&egtb_line);
if (no_capture or pawn_push in egtb_line before 50_moves_rule is reached) {
pv_length[ply] = 0;
return(0);
}
}
// Record EGTB score in hashtables -> "always" and "depth" elements.
if (!follow_pv) {
hash_entry->always.flag.bound = hash_entry->depth.flag.bound = EGTB_SCORE;
hash_entry->always.move = hash_entry->depth.move = NO_MOVE;
hash_entry->always.hashkey = hash_entry->depth.hashkey = hashkey;
hash_entry->always.score = hash_entry->depth.score = score;
hash_entry->always.depth_remaining = hash_entry->depth.depth_remaining = MAX_DEPTH;
if (age != hash_entry->depth.flag.age) {
hashtable_write++;
hash_entry->depth.flag.age = (unsigned char)age;
}
pv_length[ply] = 0;
return(alpha);
}
}
}
#endif /* EGTB */
Return to Programming and Technical Discussions
Users browsing this forum: No registered users and 8 guests