This fixes an issue with the last commit, where we could end up having
a situation like:
0.000: New move arrives, engine is busy stopping
0.200: Engine still hasn't responded, we force display (with no PV)
0.201: Engine finally comes back with a PV
1.200: Display the PV
In this case, we'd be showing no PV and score for almost a second.
Fix it by starting a new 200ms timer after the PV starts coming on,
so we'd show something at 0.401 in this case (and then 1.401 etc.).
(We don't display immediately, since it's likely to be at depth 2 or so.)
# any analysis for it, so we're on a forced timer to do so.
my $pos_calculating_started = undef;
# any analysis for it, so we're on a forced timer to do so.
my $pos_calculating_started = undef;
+# If not undef, we've output this position, but without a main PV, so we're on
+# _another_ forced timer to do so.
+my $pos_pv_started = undef;
+my $last_output_had_pv = 0;
+
setoptions($engine, \%remoteglotconf::engine_config);
uciprint($engine, "ucinewgame");
setoptions($engine, \%remoteglotconf::engine_config);
uciprint($engine, "ucinewgame");
output_json(1);
}
$pos_calculating_started = [Time::HiRes::gettimeofday];
output_json(1);
}
$pos_calculating_started = [Time::HiRes::gettimeofday];
+ $pos_pv_started = undef;
# Ask the engine to stop; we will throw away its data until it
# sends us "bestmove", signaling the end of it.
# Ask the engine to stop; we will throw away its data until it
# sends us "bestmove", signaling the end of it.
uciprint($engine, "go infinite");
$pos_calculating = $pos;
$pos_calculating_started = [Time::HiRes::gettimeofday];
uciprint($engine, "go infinite");
$pos_calculating = $pos;
$pos_calculating_started = [Time::HiRes::gettimeofday];
+ $pos_pv_started = undef;
if (defined($engine2)) {
if (defined($pos_calculating_second_engine)) {
if (defined($engine2)) {
if (defined($pos_calculating_second_engine)) {
return if (!defined($pos_calculating));
return if (!defined($pos_calculating));
+ my $info = $engine->{'info'};
+
# Don't update too often.
my $wait = $remoteglotconf::update_max_interval - Time::HiRes::tv_interval($latest_update);
if (defined($pos_calculating_started)) {
my $new_pos_wait = $remoteglotconf::update_force_after_move - Time::HiRes::tv_interval($pos_calculating_started);
$wait = $new_pos_wait if ($new_pos_wait < $wait);
}
# Don't update too often.
my $wait = $remoteglotconf::update_max_interval - Time::HiRes::tv_interval($latest_update);
if (defined($pos_calculating_started)) {
my $new_pos_wait = $remoteglotconf::update_force_after_move - Time::HiRes::tv_interval($pos_calculating_started);
$wait = $new_pos_wait if ($new_pos_wait < $wait);
}
+ if (!$last_output_had_pv && has_pv($info)) {
+ if (!defined($pos_pv_started)) {
+ $pos_pv_started = [Time::HiRes::gettimeofday];
+ }
+ # We just got initial PV, and we're in a hurry since we gave out a blank one earlier,
+ # so give us just 200ms more to increase the quality and then force a display.
+ my $new_pos_wait = $remoteglotconf::update_force_after_move - Time::HiRes::tv_interval($pos_pv_started);
+ $wait = $new_pos_wait if ($new_pos_wait < $wait);
+ }
if ($wait > 0.0) {
$output_timer = AnyEvent->timer(after => $wait + 0.01, cb => \&output);
return;
}
if ($wait > 0.0) {
$output_timer = AnyEvent->timer(after => $wait + 0.01, cb => \&output);
return;
}
+ $pos_pv_started = undef;
- my $info = $engine->{'info'};
-
# We're outputting something for this position now, so the special handling
# for new positions is off.
undef $pos_calculating_started;
# We're outputting something for this position now, so the special handling
# for new positions is off.
undef $pos_calculating_started;
output_screen();
output_json(0);
$latest_update = [Time::HiRes::gettimeofday];
output_screen();
output_json(0);
$latest_update = [Time::HiRes::gettimeofday];
+ $last_output_had_pv = has_pv($info);
+}
+
+sub has_pv {
+ my $info = shift;
+ return 1 if (exists($info->{'pv'}) && (scalar(@{$info->{'pv'}}) > 0));
+ return 1 if (exists($info->{'pv1'}) && (scalar(@{$info->{'pv1'}}) > 0));
+ return 0;