Hello!
Just wondering if anyone knows how xboard handles the new game race condition in "protover 1" engines?
Specifically, when an engine's opponent resigns for example, the GUI would send "result" to both engines, and then set up engines for a new game... and then the engine that didn't resign would output a move from the previous game, before processing the new command.
If the move is illegal on new board that can be ignored, but there's a chance that the move will happen to be legal on the new board, and the engine may happen to be playing white the next game. That would be very bad.
On "protover 2" engines this can be solved using ping, but what about "protover 1" engines, and "protover 2" engines that don't support ping?
Thanks
Handling xboard new game race condition in protover 1 engine
Moderators: hgm, Rebel, chrisw
-
- Posts: 793
- Joined: Sun Aug 03, 2014 4:48 am
- Location: London, UK
Handling xboard new game race condition in protover 1 engine
Disclosure: I work for DeepMind on the AlphaZero project, but everything I say here is personal opinion and does not reflect the views of DeepMind / Alphabet.
-
- Posts: 27811
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Handling xboard new game race condition in protover 1 en
It doesn't. This is why protover 2 / ping was invented.
The move from the previous game will be taken as a move for the new game, which usually leads to an immediate forfeit. If it happens to be legal in the opening position, the true move will be ignored by XBoard as an out-of-turn move, and as it usually will be a different on this will cause a discrepancy between XBoard's idea of the position and the engine's, leading to an illegal move later.
The only remedy is to specify a pause between games long enough that the engine would typically have moved before the new game starts.
The move from the previous game will be taken as a move for the new game, which usually leads to an immediate forfeit. If it happens to be legal in the opening position, the true move will be ignored by XBoard as an out-of-turn move, and as it usually will be a different on this will cause a discrepancy between XBoard's idea of the position and the engine's, leading to an illegal move later.
The only remedy is to specify a pause between games long enough that the engine would typically have moved before the new game starts.
-
- Posts: 793
- Joined: Sun Aug 03, 2014 4:48 am
- Location: London, UK
Re: Handling xboard new game race condition in protover 1 en
Aah I see. That is unfortunate . Was hoping there would be a workaround or something.hgm wrote:It doesn't. This is why protover 2 / ping was invented.
The move from the previous game will be taken as a move for the new game, which usually leads to an immediate forfeit. If it happens to be legal in the opening position, the true move will be ignored by XBoard as an out-of-turn move, and as it usually will be a different on this will cause a discrepancy between XBoard's idea of the position and the engine's, leading to an illegal move later.
The only remedy is to specify a pause between games long enough that the engine would typically have moved before the new game starts.
Disclosure: I work for DeepMind on the AlphaZero project, but everything I say here is personal opinion and does not reflect the views of DeepMind / Alphabet.
-
- Posts: 793
- Joined: Sun Aug 03, 2014 4:48 am
- Location: London, UK
Re: Handling xboard new game race condition in protover 1 en
Looks like some old engines will actually respond to "ping" with "Illegal move: ping 3".
I guess that would work as an engine-specific workaround (to just look for "ping x" in any error message sent back).
This is the case with Phalanx.
I guess that would work as an engine-specific workaround (to just look for "ping x" in any error message sent back).
This is the case with Phalanx.
Disclosure: I work for DeepMind on the AlphaZero project, but everything I say here is personal opinion and does not reflect the views of DeepMind / Alphabet.
-
- Posts: 27811
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Handling xboard new game race condition in protover 1 en
There is a general work-around option in XBoard to make it believe the engine has features that it doesn't:
-firstFeatures "ping=1 setboard=1"
would make XBoard believe the engine supports ping and setboard. (This is processed after the engine has sent feature done=1 or the features timeout, so it would overrule whatever the engine really said, in case these were duplicats.) This way you can force XBoard to send ping even to v1 engines.
Of course this will thouroughly wreck things if the engine does not reply with 'pong'. But perhaps InBetween can be used to substitute pong for the engine's error response to 'ping' (whether it considers it an Illegal move or an Unknown command). But this would only work if the error-response preserves the number. E.g. in the Phalanx case you could have InBetween replace 'Illegal move: ping' by 'pong' in the engine->GUI channel.
-firstFeatures "ping=1 setboard=1"
would make XBoard believe the engine supports ping and setboard. (This is processed after the engine has sent feature done=1 or the features timeout, so it would overrule whatever the engine really said, in case these were duplicats.) This way you can force XBoard to send ping even to v1 engines.
Of course this will thouroughly wreck things if the engine does not reply with 'pong'. But perhaps InBetween can be used to substitute pong for the engine's error response to 'ping' (whether it considers it an Illegal move or an Unknown command). But this would only work if the error-response preserves the number. E.g. in the Phalanx case you could have InBetween replace 'Illegal move: ping' by 'pong' in the engine->GUI channel.
-
- Posts: 793
- Joined: Sun Aug 03, 2014 4:48 am
- Location: London, UK
Re: Handling xboard new game race condition in protover 1 en
Ah I see. That makes sense.hgm wrote:There is a general work-around option in XBoard to make it believe the engine has features that it doesn't:
-firstFeatures "ping=1 setboard=1"
would make XBoard believe the engine supports ping and setboard. (This is processed after the engine has send feature done=1 or the features timeout, so it would overrule whatever the engine really said, in case these were duplicats.) This way you can force XBoard to send ping even to v1 engines.
Of course this will thouroughly wreck things if the engine does not reply with 'pong'. But perhaps InBetween can be used to substitute pong for the engine's error response to 'ping' (whether it considers it an Illegal move or an Unknown command). But this would only work if the error-response preserves the number. E.g. in the Phalanx case you could have InBetween replace 'Illegal move: ping' by 'pong' in the engine->GUI channel.
I am actually developing my own thing that matches chess engines since I can't have any UI library dependency (http://talkchess.com/forum/viewtopic.php?t=53254).
Since my "GUI" only ever has 1 ping outstanding at a time, when I send a ping, I basically just keep discarding engine output until I see something coming back with either "ping" or "pong". Haven't tried it with other engines, yet, but works with Phalanx.
Disclosure: I work for DeepMind on the AlphaZero project, but everything I say here is personal opinion and does not reflect the views of DeepMind / Alphabet.
-
- Posts: 27811
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Handling xboard new game race condition in protover 1 en
How do you solve the problem of multiple input sources and timer events? Create a separate input thread for every engine, and let it do blocking input? And use SIGALRM to set up the next timer event?
If you have solved these problems, it might be easier to just hack the GUI-dependence out of XBoard. By making all non-static routines in gtk/xoptions.c into dummies (and deleting the static ones). Basically you would only have to provide a new routines AddInputSource and RemoveInputSource, and rewite the timer handling in gtk/xtimer.c. And delete all the gtk-referring code out of gtk/xboard.c.
The timer handling seems the most tricky, as there can be several timeouts pending simultaneously in XBoard. (A dedicated one for making the clock tick, and a general one for all other events.)
If you have solved these problems, it might be easier to just hack the GUI-dependence out of XBoard. By making all non-static routines in gtk/xoptions.c into dummies (and deleting the static ones). Basically you would only have to provide a new routines AddInputSource and RemoveInputSource, and rewite the timer handling in gtk/xtimer.c. And delete all the gtk-referring code out of gtk/xboard.c.
The timer handling seems the most tricky, as there can be several timeouts pending simultaneously in XBoard. (A dedicated one for making the clock tick, and a general one for all other events.)
-
- Posts: 793
- Joined: Sun Aug 03, 2014 4:48 am
- Location: London, UK
Re: Handling xboard new game race condition in protover 1 en
For multiple input sources I am using select(). It's easier for me because I don't need to support Windows.hgm wrote:How do you solve the problem of multiple input sources and timer events? Create a separate input thread for every engine, and let it do blocking input? And use SIGALRM to set up the next timer event?
If you have solved these problems, it might be easier to just hack the GUI-dependence out of XBoard. By making all non-static routines in gtk/xoptions.c into dummies (and deleting the static ones). Basically you would only have to provide a new routines AddInputSource and RemoveInputSource, and rewite the timer handling in gtk/xtimer.c. And delete all the gtk-referring code out of gtk/xboard.c.
The timer handling seems the most tricky, as there can be several timeouts pending simultaneously in XBoard. (A dedicated one for making the clock tick, and a general one for all other events.)
I am doing select() with timeouts, and check the clocks at each timeout.
I think the main difference is that I am not making it event driven. So my main loop looks like this (pseudo code) -
Code: Select all
while (game_still_ongoing)
{
select(both_engine’s_input, timeout = 100ms);
// these are asynchronous - they will only process what’s available already
// in the pipes, and not block
engine1.process_pending_inputs();
engine2.process_pending_inputs();
if (either_engine_made_a_move_or_made_draw_offer)
{
pass_it_on_to_the_other_engine();
}
check_clocks();
}
Disclosure: I work for DeepMind on the AlphaZero project, but everything I say here is personal opinion and does not reflect the views of DeepMind / Alphabet.
-
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: Handling xboard new game race condition in protover 1 en
One other note. I decided to give up on passing draw offers between programs. Too many do it wrong, so I just gave up. My referee ends a game when a draw state is seen (50 moves, 3-fold rep, stalemate, insufficient material) otherwise "draw" is ignored, which solved a lot of problems. I can disable this, but it only seems to be safe with Crafty vs Crafty matches, to specifically test accepting draw offers which I do a bit differently from some.matthewlai wrote:For multiple input sources I am using select(). It's easier for me because I don't need to support Windows.hgm wrote:How do you solve the problem of multiple input sources and timer events? Create a separate input thread for every engine, and let it do blocking input? And use SIGALRM to set up the next timer event?
If you have solved these problems, it might be easier to just hack the GUI-dependence out of XBoard. By making all non-static routines in gtk/xoptions.c into dummies (and deleting the static ones). Basically you would only have to provide a new routines AddInputSource and RemoveInputSource, and rewite the timer handling in gtk/xtimer.c. And delete all the gtk-referring code out of gtk/xboard.c.
The timer handling seems the most tricky, as there can be several timeouts pending simultaneously in XBoard. (A dedicated one for making the clock tick, and a general one for all other events.)
I am doing select() with timeouts, and check the clocks at each timeout.
I think the main difference is that I am not making it event driven. So my main loop looks like this (pseudo code) -
It's very different from how xboard is organized (since xboard is event driven and need to handle user input).Code: Select all
while (game_still_ongoing) { select(both_engine’s_input, timeout = 100ms); // these are asynchronous - they will only process what’s available already // in the pipes, and not block engine1.process_pending_inputs(); engine2.process_pending_inputs(); if (either_engine_made_a_move_or_made_draw_offer) { pass_it_on_to_the_other_engine(); } check_clocks(); }
-
- Posts: 793
- Joined: Sun Aug 03, 2014 4:48 am
- Location: London, UK
Re: Handling xboard new game race condition in protover 1 en
How do engines do it wrong? I thought all engines have to do is "offer draw" when they see a draw offer and want to take it.bob wrote:One other note. I decided to give up on passing draw offers between programs. Too many do it wrong, so I just gave up. My referee ends a game when a draw state is seen (50 moves, 3-fold rep, stalemate, insufficient material) otherwise "draw" is ignored, which solved a lot of problems. I can disable this, but it only seems to be safe with Crafty vs Crafty matches, to specifically test accepting draw offers which I do a bit differently from some.matthewlai wrote:For multiple input sources I am using select(). It's easier for me because I don't need to support Windows.hgm wrote:How do you solve the problem of multiple input sources and timer events? Create a separate input thread for every engine, and let it do blocking input? And use SIGALRM to set up the next timer event?
If you have solved these problems, it might be easier to just hack the GUI-dependence out of XBoard. By making all non-static routines in gtk/xoptions.c into dummies (and deleting the static ones). Basically you would only have to provide a new routines AddInputSource and RemoveInputSource, and rewite the timer handling in gtk/xtimer.c. And delete all the gtk-referring code out of gtk/xboard.c.
The timer handling seems the most tricky, as there can be several timeouts pending simultaneously in XBoard. (A dedicated one for making the clock tick, and a general one for all other events.)
I am doing select() with timeouts, and check the clocks at each timeout.
I think the main difference is that I am not making it event driven. So my main loop looks like this (pseudo code) -
It's very different from how xboard is organized (since xboard is event driven and need to handle user input).Code: Select all
while (game_still_ongoing) { select(both_engine’s_input, timeout = 100ms); // these are asynchronous - they will only process what’s available already // in the pipes, and not block engine1.process_pending_inputs(); engine2.process_pending_inputs(); if (either_engine_made_a_move_or_made_draw_offer) { pass_it_on_to_the_other_engine(); } check_clocks(); }
Do they assume the game is over?
I am hesitant to ignore draw offers, because I am very interested in saving time (to play more games), and if engines agree to draw, it would save a lot of time in some cases.
Disclosure: I work for DeepMind on the AlphaZero project, but everything I say here is personal opinion and does not reflect the views of DeepMind / Alphabet.