if (bpfen.empty()) {
break;
}
+ string prev_pos_hash = read_hex_line(stdin);
- int bucket = hash_key_to_bucket(bpfen.data(), bpfen.size(), num_buckets);
+ string searchkey = bpfen + prev_pos_hash;
+ int bucket = hash_key_to_bucket(searchkey.data(), searchkey.size(), num_buckets);
if (mtbls[bucket] == NULL) {
char filename[256];
snprintf(filename, sizeof(filename), "%s.part%04d", argv[1], bucket);
uint16_t board_hash = util::Hash32(bpfen.data(), bpfen.size());
printf("%d\n", board_hash);
- mtbl_iter *it = mtbl_source_get_prefix(srcs[bucket], (const uint8_t *)bpfen.data(), bpfen.size());
+ mtbl_iter *it = mtbl_source_get_prefix(srcs[bucket], (const uint8_t *)searchkey.data(), searchkey.size());
const uint8_t *key, *val;
size_t len_key, len_val;
my $cgi = CGI->new;
my $fen = $ARGV[0];
+my $filter_prev_pos_hash = $ARGV[1] // 0;
my ($chld_out, $chld_in);
my $pid = IPC::Open2::open2($chld_out, $chld_in, "./binlookup", "./open.mtbl", "40");
# Root position.
my $pos = Position->from_fen($fen);
-my $hex = unpack('H*', $pos->bitpacked_fen);
-print $chld_in $hex, "\n";
+my $bpfen_hex = unpack('H*', $pos->bitpacked_fen);
+my $prev_pos_hash_hex = unpack('H*', pack('S', $filter_prev_pos_hash));
+print $chld_in $bpfen_hex, "\n", $prev_pos_hash_hex, "\n";
chomp (my $line = <$chld_out>); # Root position hash.
print $line, "\n";
-chomp (my $line = <$chld_out>); # Actual stats.
+chomp ($line = <$chld_out>); # Actual stats.
print $line, "\n";
my ($white, $draw, $black, $opening_num, $white_avg_elo, $black_avg_elo, $num_elo, $timestamp, $pgn_file_number, $pgn_start_position, @moves) = split / /, $line;
for my $move (@moves) {
my ($np, $uci_move) = $pos->make_pretty_move($move);
my $hex = unpack('H*', $np->bitpacked_fen);
- print $chld_in $hex, "\n";
+ print $chld_in $hex, "\n\n";
my $line = <$chld_out>; # Ignore position hash.
$line = <$chld_out>;
print "$move $line";
</div>
</div>
<div id="analysis">
+ <p>
+ <label>
+ <input type="checkbox" name="includetransp" checked="checked" onclick="javascript:set_includetransp(this.checked)" />Include transpositions
+ </label>
+ </p>
<table>
<thead>
<tr id="headings">
var board = null;
var history = [];
var move_override = 0;
+var includetransp = true;
var entity_map = {
"&": "&",
});
}
-var get_game = function() {
+var get_game = function(skip_last_move) {
+ var moves_to_drop = 0;
+ if (skip_last_move === true) {
+ moves_to_drop = 1;
+ }
+
var game = new Chess();
- for (var i = 0; i < move_override; ++i) {
+ for (var i = 0; i < move_override - moves_to_drop; ++i) {
game.move(history[i]);
}
return game;
var fetch_analysis = function() {
var game = get_game();
+ var fen = game.fen();
+ var prevfen = "";
+ if (move_override > 0) {
+ prevfen = get_game(true).fen();
+ }
$.ajax({
- url: "/opening-stats.pl?fen=" + encodeURIComponent(game.fen())
+ url: "/opening-stats.pl?fen=" + encodeURIComponent(fen) +
+ ";prevfen=" + encodeURIComponent(prevfen) +
+ ";includetransp=" + (includetransp ? 1 : 0)
}).done(function(data, textstatus, xhr) {
show_lines(data, game);
});
}
}
+var set_includetransp = function(value) {
+ includetransp = value;
+ update();
+}
+window['set_includetransp'] = set_includetransp;
+
var make_move = function(move) {
if (move_override < history.length && history[move_override] == move) {
// User effectively only moved forward in history.
history.push(new_history[i].san);
}
move_override = history.length;
- update();
};
// update the board position after the piece snap
var onSnapEnd = function() {
var game = get_game();
board.position(game.fen());
- fetch_analysis();
+ update();
};
var init = function() {
# Root position. Basically ignore everything except the opening (and later some root game stuff).
my $fen = $cgi->param('fen') // 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1';
+my $prevfen = $cgi->param('prevfen') // '';
my $includetransp = $cgi->param('includetransp') // 1;
my $pos = Position->from_fen($fen);
-my ($json_root_pos, $root_aux_data) = get_json_move($pos, undef, $chld_in, $chld_out); # TODO: include previous hash if $includetransp == 0
-my $opening = $openings{$json_root_pos->{'opening_num'}} // 'A00: Start position';
+my ($json_root_pos, $root_aux_data);
+if ($includetransp) {
+ ($json_root_pos, $root_aux_data) = get_json_move($pos, undef, $chld_in, $chld_out);
+} else {
+ my $prev_pos_hash = 0;
+ if ($prevfen ne '') {
+ my $prevpos = Position->from_fen($prevfen);
+ my (undef, $prev_aux_data) = get_json_move($prevpos, undef, $chld_in, $chld_out);
+ $prev_pos_hash = $prev_aux_data->{'pos_hash'};
+ }
+ ($json_root_pos, $root_aux_data) = get_json_move($pos, $prev_pos_hash, $chld_in, $chld_out);
+}
+my $opening = $openings{$json_root_pos->{'opening_num'}} // 'A00: Start position';
my @json_moves = ($json_root_pos);
my $root_game;
sub get_json_move {
my ($pos, $filter_prev_pos_hash, $chld_in, $chld_out) = @_;
- my $hex = unpack('H*', $pos->bitpacked_fen);
+ my $bpfen_hex = unpack('H*', $pos->bitpacked_fen);
+ my $prev_pos_hash_hex = '';
if (defined($filter_prev_pos_hash)) {
- $hex .= unpack('H*', pack('S', $filter_prev_pos_hash));
+ $prev_pos_hash_hex .= unpack('H*', pack('S', $filter_prev_pos_hash));
}
- print $chld_in $hex, "\n";
+ print $chld_in $bpfen_hex, "\n", $prev_pos_hash_hex, "\n";
# Read the hash of this position.
chomp (my $pos_hash = <$chld_out>);
chomp (my $line = <$chld_out>);
if ($line eq '-') {
+ warn "Missing pos '" . $pos->fen . "' " . $filter_prev_pos_hash;
return ({}, {});
}