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',
# Program starts here
$SIG{ALRM} = sub { output_screen(); };
+my $latest_update = undef;
$| = 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 = '';
if ($nfound > 0 && vec($rout, fileno($engine->{'read'}), 1) == 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 @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;
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;
} 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'};
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'};
#
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'};
}
}
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) {
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 {
} 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;
}
}
sub open_engine {
- my $cmdline = shift;
+ my ($cmdline, $tag) = @_;
my ($uciread, $uciwrite);
my $pid = IPC::Open2::open2($uciread, $uciwrite, $cmdline);
write => $uciwrite,
info => {},
ids => {},
+ tag => $tag,
};
uciprint($engine, "uci");