]> git.sesse.net Git - remoteglot/blobdiff - remoteglot.pl
Add local time management, for when incoming time is bad or nonexistent.
[remoteglot] / remoteglot.pl
index aaaed104ea94a2fd73ab316678129b4f66b5bf18..7b3d9670771b14d6d3e4608ea237cd94b02c10c3 100755 (executable)
@@ -326,15 +326,21 @@ sub handle_pgn {
 
 sub handle_position {
        my ($pos) = @_;
-       find_clock_start($pos);
+       find_clock_start($pos, $pos_calculating);
                
-       # if this is already in the queue, ignore it
-       return if (defined($pos_waiting) && $pos->fen() eq $pos_waiting->fen());
+       # if this is already in the queue, ignore it (just update the result)
+       if (defined($pos_waiting) && $pos->fen() eq $pos_waiting->fen()) {
+               $pos_waiting->{'result'} = $pos->{'result'};
+               return;
+       }
 
        # if we're already chewing on this and there's nothing else in the queue,
        # also ignore it
-       return if (!defined($pos_waiting) && defined($pos_calculating) &&
-                $pos->fen() eq $pos_calculating->fen());
+       if (!defined($pos_waiting) && defined($pos_calculating) &&
+           $pos->fen() eq $pos_calculating->fen()) {
+               $pos_calculating->{'result'} = $pos->{'result'};
+               return;
+       }
 
        # if we're already thinking on something, stop and wait for the engine
        # to approve
@@ -990,11 +996,8 @@ sub extract_clock {
        # Look for extended PGN clock tags.
        my $tags = $pgn->tags;
        if (exists($tags->{'WhiteClock'}) && exists($tags->{'BlackClock'})) {
-               $pos->{'white_clock'} = $tags->{'WhiteClock'};
-               $pos->{'black_clock'} = $tags->{'BlackClock'};
-
-               $pos->{'white_clock'} =~ s/\b(\d)\b/0$1/g;
-               $pos->{'black_clock'} =~ s/\b(\d)\b/0$1/g;
+               $pos->{'white_clock'} = hms_to_sec($tags->{'WhiteClock'});
+               $pos->{'black_clock'} = hms_to_sec($tags->{'BlackClock'});
                return;
        }
 
@@ -1009,12 +1012,12 @@ sub extract_clock {
 
        if (exists($comments->{$white_key}) &&
            exists($comments->{$black_key}) &&
-           $comments->{$white_key} =~ /tl=(\d+:\d+:\d+)/ &&
-           $comments->{$black_key} =~ /tl=(\d+:\d+:\d+)/) {
-               $comments->{$white_key} =~ /tl=(\d+:\d+:\d+)/;
-               $pos->{'white_clock'} = $1;
-               $comments->{$black_key} =~ /tl=(\d+:\d+:\d+)/;
-               $pos->{'black_clock'} = $1;
+           $comments->{$white_key} =~ /(?:tl=|clk )(\d+:\d+:\d+)/ &&
+           $comments->{$black_key} =~ /(?:tl=|clk )(\d+:\d+:\d+)/) {
+               $comments->{$white_key} =~ /(?:tl=|clk )(\d+:\d+:\d+)/;
+               $pos->{'white_clock'} = hms_to_sec($1);
+               $comments->{$black_key} =~ /(?:tl=|clk )(\d+:\d+:\d+)/;
+               $pos->{'black_clock'} = hms_to_sec($1);
                return;
        }
 
@@ -1022,8 +1025,15 @@ sub extract_clock {
        delete $pos->{'black_clock'};
 }
 
+sub hms_to_sec {
+       my $hms = shift;
+       return undef if (!defined($hms));
+       $hms =~ /(\d+):(\d+):(\d+)/;
+       return $1 * 3600 + $2 * 60 + $3;
+}
+
 sub find_clock_start {
-       my $pos = shift;
+       my ($pos, $prev_pos) = @_;
 
        # If the game is over, the clock is stopped.
        if (exists($pos->{'result'}) &&
@@ -1035,10 +1045,14 @@ sub find_clock_start {
 
        # When we don't have any moves, we assume the clock hasn't started yet.
        if ($pos->{'move_num'} == 1 && $pos->{'toplay'} eq 'W') {
+               if (defined($remoteglotconf::adjust_clocks_before_move)) {
+                       &$remoteglotconf::adjust_clocks_before_move(\$pos->{'white_clock'}, \$pos->{'black_clock'}, 1, 'W');
+               }
                return;
        }
 
        # TODO(sesse): Maybe we can get the number of moves somehow else for FICS games.
+       # The history is needed for id_for_pos.
        if (!exists($pos->{'pretty_history'})) {
                return;
        }
@@ -1055,18 +1069,36 @@ sub find_clock_start {
 
        # OK, we haven't seen this position before, so we assume the move
        # happened right now.
+
+       # See if we should do our own clock management (ie., clock information
+       # is spurious or non-existent).
+       if (defined($remoteglotconf::adjust_clocks_before_move)) {
+               my $wc = $pos->{'white_clock'} // $prev_pos->{'white_clock'};
+               my $bc = $pos->{'black_clock'} // $prev_pos->{'black_clock'};
+               if (defined($prev_pos->{'white_clock_target'})) {
+                       $wc = $prev_pos->{'white_clock_target'} - time;
+               }
+               if (defined($prev_pos->{'black_clock_target'})) {
+                       $bc = $prev_pos->{'black_clock_target'} - time;
+               }
+               &$remoteglotconf::adjust_clocks_before_move(\$wc, \$bc, $pos->{'move_num'}, $pos->{'toplay'});
+               $pos->{'white_clock'} = $wc;
+               $pos->{'black_clock'} = $bc;
+       }
+
        my $key = ($pos->{'toplay'} eq 'W') ? 'white_clock' : 'black_clock';
        if (!exists($pos->{$key})) {
                # No clock information.
                return;
        }
-       $pos->{$key} =~ /(\d+):(\d+):(\d+)/;
-       my $time_left = $1 * 3600 + $2 * 60 + $3;
+       my $time_left = $pos->{$key};
        $clock_target_for_pos{$id} = time + $time_left;
        if ($pos->{'toplay'} eq 'W') {
                $pos->{'white_clock_target'} = $clock_target_for_pos{$id};
+               delete $pos->{'black_clock_target'};
        } else {
                $pos->{'black_clock_target'} = $clock_target_for_pos{$id};
+               delete $pos->{'white_clock_target'};
        }
 }