# Configuration
my $server = "freechess.org";
-my $target = "Sesse";
+my $target = "22";
# my $engine = "/usr/games/toga2";
my $engine = "wine Rybkav2.3.2a.mp.w32.exe";
my $telltarget = undef; # undef to be silent
my ($last_move, $last_tell);
my $last_text = '';
my $last_told_text = '';
+my ($board_waiting, $board_calculating);
uciprint("uci");
}
uciprint("setoption name UCI_AnalyseMode value true");
+uciprint("setoption name Preserve Analysis value true");
uciprint("setoption name NalimovPath value c:\\nalimov");
uciprint("setoption name NalimovUsage value Rarely");
uciprint("setoption name Hash value 1024");
-# uciprint("setoption name MultiPV value 3");
+uciprint("setoption name MultiPV value 3");
# uciprint("setoption name Contempt value 1000");
# uciprint("setoption name Outlook value Ultra Optimistic");
uciprint("ucinewgame");
$line =~ tr/\r//d;
if ($line =~ /^<12> /) {
my $fen = style12_to_fen($line);
- uciprint("stop");
- uciprint("position fen $fen");
- uciprint("go infinite");
+
+ # if this is already in the queue, ignore it
+ next if (defined($board_waiting) && $fen eq $board_waiting);
+
+ # if we're already chewing on this and there's nothing else in the queue,
+ # also ignore it
+ next if (!defined($board_waiting) && defined($board_calculating) &&
+ $fen eq $board_calculating);
+
+ # if we're already thinking on something, stop and wait for the engine
+ # to approve
+ if (defined($board_calculating)) {
+ uciprint("stop");
+ $board_waiting = $fen;
+ } else {
+ # it's wrong just to give the FEN (the move history is useful,
+ # and per the UCI spec, we should really have sent "ucinewgame"),
+ # but it's easier
+ uciprint("position fen $fen");
+ uciprint("go infinite");
+ }
+ %uciinfo = ();
$last_move = time;
#
parse_ids(@ids);
}
+ if ($line =~ /^bestmove/) {
+ if (defined($board_calculating)) {
+ uciprint("position fen $board_waiting");
+ uciprint("go infinite");
+
+ $board_calculating = $board_waiting;
+ $board_waiting = undef;
+ }
+ }
}
sub parse_infos {
}
};
if ($@) {
+ %uciinfo = ();
return;
}
}
return unless (exists($ficsinfo{'board'}));
+
+ #
+ # Some programs _always_ report MultiPV, even with only one PV.
+ # In this case, we simply use that data as if MultiPV was never
+ # specified.
+ #
+ if (exists($uciinfo{'pv1'}) && !exists($uciinfo{'pv2'})) {
+ for my $key qw(pv score_cp score_mate nodes nps depth seldepth tbhits) {
+ if (exists($uciinfo{$key . '1'}) && !exists($uciinfo{$key})) {
+ $uciinfo{$key} = $uciinfo{$key . '1'};
+ }
+ }
+ }
if (exists($uciinfo{'pv1'}) && exists($uciinfo{'pv2'})) {
# multi-PV
while (exists($uciinfo{'pv' . $mpv})) {
$text .= sprintf " PV%2u", $mpv;
my $score = short_score(\%uciinfo, \%ficsinfo, $mpv);
- $text .= " ($score)" if (!defined($score));
+ $text .= " ($score)" if (defined($score));
if (exists($uciinfo{'nodes' . $mpv}) && exists($uciinfo{'nps' . $mpv}) && exists($uciinfo{'depth' . $mpv})) {
$text .= sprintf " (%5u kn, %3u kn/s, %2u ply)",
++$mpv;
}
} else {
- #
- # Some programs _always_ report MultiPV, even with only one PV.
- # In this case, we simply use that data as if MultiPV was never
- # specified.
- #
- if (exists($uciinfo{'pv1'})) {
- for my $key qw(pv score_cp score_mate nodes nps depth seldepth tbhits) {
- if (exists($uciinfo{$key . '1'}) && !exists($uciinfo{$key})) {
- $uciinfo{$key} = $uciinfo{$key . '1'};
- }
- }
- }
-
# single-PV
my $score = long_score(\%uciinfo, \%ficsinfo, '');
$text .= " $score\n" if defined($score);
$last_text = $text;
}
+ # Now construct the tell text, if any
+ return if (!defined($telltarget));
+
+ my $tell_text = '';
+
+ if (exists($uciid{'name'})) {
+ $tell_text .= "Analysis by $uciid{'name'} -- see http://analysis.sesse.net/ for more information\n";
+ } else {
+ $tell_text .= "Computer analysis -- http://analysis.sesse.net/ for more information\n";
+ }
+
+ if (exists($uciinfo{'pv1'}) && exists($uciinfo{'pv2'})) {
+ # multi-PV
+ my $mpv = 1;
+ while (exists($uciinfo{'pv' . $mpv})) {
+ $tell_text .= sprintf " PV%2u", $mpv;
+ my $score = short_score(\%uciinfo, \%ficsinfo, $mpv);
+ $tell_text .= " ($score)" if (defined($score));
+
+ if (exists($uciinfo{'depth' . $mpv})) {
+ $tell_text .= sprintf " (%2u ply)", $uciinfo{'depth' . $mpv};
+ }
+
+ $tell_text .= ": ";
+ $tell_text .= join(', ', prettyprint_pv($ficsinfo{'board'}, @{$uciinfo{'pv' . $mpv}}));
+ $tell_text .= "\n";
+ ++$mpv;
+ }
+ } else {
+ # single-PV
+ my $score = long_score(\%uciinfo, \%ficsinfo, '');
+ $tell_text .= " $score\n" if defined($score);
+ $tell_text .= " PV: " . join(', ', prettyprint_pv($ficsinfo{'board'}, @{$uciinfo{'pv'}}));
+ if (exists($uciinfo{'depth'})) {
+ $tell_text .= sprintf " (depth %u ply)", $uciinfo{'depth'};
+ }
+ $tell_text .= "\n";
+ }
+
# see if a new tell is called for -- it is if the delay has expired _and_
# this is not simply a repetition of the last one
- if ($last_told_text ne $text && defined($telltarget)) {
+ if ($last_told_text ne $tell_text) {
my $now = time;
for my $iv (@tell_intervals) {
last if ($now - $last_move < $iv);
next if ($last_tell - $last_move >= $iv);
- for my $line (split /\n/, $text) {
+ for my $line (split /\n/, $tell_text) {
$t->print("tell $telltarget [$target] $line");
}