]> git.sesse.net Git - remoteglot/blobdiff - remoteglot.pl
Force faster updates if our last output was without a PV.
[remoteglot] / remoteglot.pl
index d8a7925c9137cfe548b0b9729a98f8daf3defac7..06549f2a53813c9969d0e960cb078cf9c32583a6 100755 (executable)
@@ -76,6 +76,15 @@ my $last_move;
 my $last_text = '';
 my ($pos_calculating, $pos_calculating_second_engine);
 
+# If not undef, we've started calculating this position but haven't ever given out
+# 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");
 
@@ -388,12 +397,23 @@ sub handle_position {
                # the position.)
                #
                # Do not output anything new to the main analysis; that's
-               # going to be obsolete really soon.
+               # going to be obsolete really soon. (Exception: If we've never
+               # output anything for this move, ie., it didn't hit the 200ms
+               # limit, spit it out to the user anyway. It's probably a really
+               # fast blitz game or something, and it's good to show the moves
+               # as they come in even without great analysis.)
                $pos_calculating->{'white_clock'} = $pos->{'white_clock'};
                $pos_calculating->{'black_clock'} = $pos->{'black_clock'};
                delete $pos_calculating->{'white_clock_target'};
                delete $pos_calculating->{'black_clock_target'};
-               output_json(1);
+
+               if (defined($pos_calculating_started)) {
+                       output_json(0);
+               } else {
+                       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.
@@ -411,6 +431,8 @@ sub handle_position {
        uciprint($engine, "position fen " . $pos->fen());
        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)) {
@@ -535,10 +557,14 @@ sub prettyprint_pv_no_cache {
                return ();
        }
 
-       my $pv = shift @pvs;
-       my ($from_row, $from_col, $to_row, $to_col, $promo) = parse_uci_move($pv);
-       my ($pretty, $nb) = $board->prettyprint_move($from_row, $from_col, $to_row, $to_col, $promo);
-       return ( $pretty, prettyprint_pv_no_cache($nb, @pvs) );
+       my @ret = ();
+       for my $pv (@pvs) {
+               my ($from_row, $from_col, $to_row, $to_col, $promo) = parse_uci_move($pv);
+               my ($pretty, $nb) = $board->prettyprint_move($from_row, $from_col, $to_row, $to_col, $promo);
+               push @ret, $pretty;
+               $board = $nb;
+       }
+       return @ret;
 }
 
 sub prettyprint_pv {
@@ -629,16 +655,33 @@ sub output {
 
        return if (!defined($pos_calculating));
 
+       my $info = $engine->{'info'};
+
        # Don't update too often.
-       my $age = Time::HiRes::tv_interval($latest_update);
-       if ($age < $remoteglotconf::update_max_interval) {
-               my $wait = $remoteglotconf::update_max_interval + 0.01 - $age;
-               $output_timer = AnyEvent->timer(after => $wait, cb => \&output);
+       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;
        }
+       $pos_pv_started = undef;
+       
+       # We're outputting something for this position now, so the special handling
+       # for new positions is off.
+       undef $pos_calculating_started;
        
-       my $info = $engine->{'info'};
-
        #
        # If we have tablebase data from a previous lookup, replace the
        # engine data with the data from the tablebase.
@@ -730,6 +773,14 @@ sub output {
        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;
 }
 
 sub output_screen {