X-Git-Url: https://git.sesse.net/?p=remoteglot;a=blobdiff_plain;f=remoteglot.pl;h=bb16ebcbd9931d23cc360dfac948b9faeed59c17;hp=2e0f2206bba780b5a2fd8c81674adc7168dd35fa;hb=a5d359eaff725889fd3554a7c3b7ac5088eb7c63;hpb=cf9785772b5dcb8de2376b4b1ab5951d868b3140 diff --git a/remoteglot.pl b/remoteglot.pl index 2e0f220..bb16ebc 100755 --- a/remoteglot.pl +++ b/remoteglot.pl @@ -24,6 +24,7 @@ my $engine2_cmdline = "./stockfish_13111119_x64_modern_sse42"; my $telltarget = undef; # undef to be silent my @tell_intervals = (5, 20, 60, 120, 240, 480, 960); # after each move my $uci_assume_full_compliance = 0; # dangerous :-) +my $update_max_interval = 2.0; my $second_engine_start_depth = 8; my @masters = ( 'Sesse', @@ -35,6 +36,7 @@ my @masters = ( # Program starts here $SIG{ALRM} = sub { output_screen(); }; +my $latest_update = undef; $| = 1; @@ -52,8 +54,8 @@ $| = 1; select(STDOUT); # open the chess engine -my $engine = open_engine($engine_cmdline); -my $engine2 = open_engine($engine2_cmdline); +my $engine = open_engine($engine_cmdline, 'E1'); +my $engine2 = open_engine($engine2_cmdline, 'E2'); my ($last_move, $last_tell); my $last_text = ''; my $last_told_text = ''; @@ -184,20 +186,24 @@ while (1) { # any fun on the UCI channel? if ($nfound > 0 && vec($rout, fileno($engine->{'read'}), 1) == 1) { - my $line = read_line($engine->{'read'}); - handle_uci($engine, $line, 1); + my @lines = read_lines($engine); + for my $line (@lines) { + next if $line =~ /(upper|lower)bound/; + handle_uci($engine, $line, 1); + } $sleep = 0; - # don't update too often - Time::HiRes::alarm(0.2); + output_screen(); } if ($nfound > 0 && vec($rout, fileno($engine2->{'read'}), 1) == 1) { - my $line = read_line($engine2->{'read'}); - handle_uci($engine2, $line, 0); + my @lines = read_lines($engine2); + for my $line (@lines) { + next if $line =~ /(upper|lower)bound/; + handle_uci($engine2, $line, 0); + } $sleep = 0; - # don't update too often - Time::HiRes::alarm(0.2); + output_screen(); } sleep $sleep; @@ -209,7 +215,7 @@ sub handle_uci { chomp $line; $line =~ tr/\r//d; $line =~ s/ / /g; # Sometimes needed for Zappa Mexico - print UCILOG localtime() . " <= $line\n"; + print UCILOG localtime() . " $engine->{'tag'} <= $line\n"; if ($line =~ /^info/) { my (@infos) = split / /, $line; shift @infos; @@ -235,7 +241,7 @@ sub handle_uci { } else { if (defined($move_calculating_second_engine)) { my $move = $refutation_moves{$move_calculating_second_engine}; - $move->{'pv'} = $engine->{'info'}{'pv'}; + $move->{'pv'} = $engine->{'info'}{'pv'} // $engine->{'info'}{'pv1'}; $move->{'score_cp'} = $engine->{'info'}{'score_cp'} // $engine->{'info'}{'score_cp1'} // 0; $move->{'score_mate'} = $engine->{'info'}{'score_mate'} // $engine->{'info'}{'score_mate1'}; $move->{'toplay'} = $pos_calculating->{'toplay'}; @@ -615,9 +621,17 @@ sub prettyprint_pv { sub output_screen { #return; - + return if (!defined($pos_calculating)); + # Don't update too often. + my $age = Time::HiRes::tv_interval($latest_update); + if ($age < $update_max_interval) { + Time::HiRes::alarm($update_max_interval + 0.01 - $age); + return; + } + $latest_update = [Time::HiRes::gettimeofday]; + my $info = $engine->{'info'}; my $id = $engine->{'id'}; @@ -670,7 +684,7 @@ sub output_screen { # if (exists($info->{'pv1'}) && !exists($info->{'pv2'})) { for my $key (qw(pv score_cp score_mate nodes nps depth seldepth tbhits)) { - if (exists($info->{$key . '1'}) && !exists($info->{$key})) { + if (exists($info->{$key . '1'})) { $info->{$key} = $info->{$key . '1'}; } } @@ -733,7 +747,7 @@ sub output_screen { for my $move (keys %refutation_moves) { eval { my $m = $refutation_moves{$move}; - next if ($m->{'depth'} < $second_engine_start_depth); + die if ($m->{'depth'} < $second_engine_start_depth); my $pretty_move = join('', prettyprint_pv($pos_calculating->{'board'}, $move)); my @pretty_pv = prettyprint_pv($pos_calculating->{'board'}, $move, @{$m->{'pv'}}); if (scalar @pretty_pv > 5) { @@ -1024,7 +1038,7 @@ sub can_reach { sub uciprint { my ($engine, $msg) = @_; print { $engine->{'write'} } "$msg\n"; - print UCILOG localtime() . " => $msg\n"; + print UCILOG localtime() . " $engine->{'tag'} => $msg\n"; } sub short_score { @@ -1044,6 +1058,9 @@ sub short_score { } else { if (exists($info->{'score_cp' . $mpv})) { my $score = $info->{'score_cp' . $mpv} * 0.01; + if ($score == 0) { + return " 0.00"; + } if ($invert) { $score = -$score; } @@ -1160,16 +1177,18 @@ sub book_info { } sub open_engine { - my $cmdline = shift; + my ($cmdline, $tag) = @_; my ($uciread, $uciwrite); my $pid = IPC::Open2::open2($uciread, $uciwrite, $cmdline); my $engine = { pid => $pid, read => $uciread, + readbuf => '', write => $uciwrite, info => {}, - ids => {} + ids => {}, + tag => $tag, }; uciprint($engine, "uci"); @@ -1183,18 +1202,17 @@ sub open_engine { return $engine; } -sub read_line { - my $fh = shift; +sub read_lines { + my $engine = shift; # # Read until we've got a full line -- if the engine sends part of # a line and then stops we're pretty much hosed, but that should # never happen. # - my $line = ''; - while ($line !~ /\n/) { + while ($engine->{'readbuf'} !~ /\n/) { my $tmp; - my $ret = sysread $fh, $tmp, 1; + my $ret = sysread $engine->{'read'}, $tmp, 4096; if (!defined($ret)) { next if ($!{EINTR}); @@ -1203,11 +1221,17 @@ sub read_line { die "EOF from UCI engine"; } - $line .= $tmp; + $engine->{'readbuf'} .= $tmp; } - $line =~ tr/\r\n//d; - return $line; + # Blah. + my @lines = (); + while ($engine->{'readbuf'} =~ s/^([^\n]*)\n//) { + my $line = $1; + $line =~ tr/\r\n//d; + push @lines, $line; + } + return @lines; } # Find all possible legal moves.