X-Git-Url: https://git.sesse.net/?p=remoteglot;a=blobdiff_plain;f=remoteglot.pl;h=62d3aa1dbc84496be887850af91569bc82f9107e;hp=d82c20bed25034896c341b979aa9a5b36bb0fac9;hb=181097241ea4fe24cbea99a0a92736e39704e4a6;hpb=88d92e1d44ad96601281d9ce96a525ac7df90757 diff --git a/remoteglot.pl b/remoteglot.pl index d82c20b..62d3aa1 100755 --- a/remoteglot.pl +++ b/remoteglot.pl @@ -210,7 +210,6 @@ sub handle_fics { next if (!defined($pos)); if ($pos->fen() eq $pos_for_movelist->fen()) { $pos->{'history'} = \@uci_movelist; - $pos->{'pretty_history'} = \@pretty_movelist; } } $getting_movelist = 0; @@ -280,7 +279,6 @@ sub handle_pgn { push @uci_moves, $uci_move; } $pos->{'history'} = \@uci_moves; - $pos->{'pretty_history'} = $moves; # Sometimes, PGNs lose a move or two for a short while, # or people push out new ones non-atomically. @@ -713,7 +711,6 @@ sub output_json { # single-PV only for now $json->{'pv_uci'} = $info->{'pv'}; - $json->{'pv_pretty'} = [ prettyprint_pv($pos_calculating, @{$info->{'pv'}}) ]; my %refutation_lines = (); my @refutation_lines = (); @@ -734,7 +731,6 @@ sub output_json { score_sort_key => score_sort_key($info, $pos_calculating, $mpv, 0), pretty_score => short_score($info, $pos_calculating, $mpv), pretty_move => $pretty_move, - pv_pretty => \@pretty_pv, }; $refutation_lines{$pv->[0]}->{'pv_uci'} = $pv; }; @@ -742,11 +738,61 @@ sub output_json { } $json->{'refutation_lines'} = \%refutation_lines; - open my $fh, ">", $remoteglotconf::json_output . ".tmp" + my $encoded = JSON::XS::encode_json($json); + atomic_set_contents($remoteglotconf::json_output, $encoded); + + if (exists($pos_calculating->{'history'}) && + defined($remoteglotconf::json_history_dir)) { + my $halfmove_num = scalar @{$pos_calculating->{'history'}}; + (my $fen = $pos_calculating->fen()) =~ tr,/ ,-_,; + my $filename = $remoteglotconf::json_history_dir . "/move$halfmove_num-$fen.json"; + + # Overwrite old analysis (assuming it exists at all) if we're + # using a different engine, or if we've calculated deeper. + # nodes is used as a tiebreaker. Don't bother about Multi-PV + # data; it's not that important. + my ($old_engine, $old_depth, $old_nodes) = get_json_analysis_stats($filename); + my $new_depth = $json->{'depth'} // 0; + my $new_nodes = $json->{'nodes'} // 0; + if (!defined($old_engine) || + $old_engine ne $json->{'id'}{'name'} || + $new_depth > $old_depth || + ($new_depth == $old_depth && $new_nodes >= $old_nodes)) { + atomic_set_contents($filename, $encoded); + } + } +} + +sub atomic_set_contents { + my ($filename, $contents) = @_; + + open my $fh, ">", $filename . ".tmp" or return; - print $fh JSON::XS::encode_json($json); + print $fh $contents; + close $fh; + rename($filename . ".tmp", $filename); +} + +sub get_json_analysis_stats { + my $filename = shift; + + my ($engine, $depth, $nodes); + + open my $fh, "<", $filename + or return undef; + local $/ = undef; + eval { + my $json = JSON::XS::decode_json(<$fh>); + $engine = $json->{'id'}{'name'} // die; + $depth = $json->{'depth'} // 0; + $nodes = $json->{'nodes'} // 0; + }; close $fh; - rename($remoteglotconf::json_output . ".tmp", $remoteglotconf::json_output); + if ($@) { + warn "Error in decoding $filename: $@"; + return undef; + } + return ($engine, $depth, $nodes); } sub uciprint {