From 84758bbacfaaceb5e328ff01fe2c003bc58e939c Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sat, 24 Dec 2022 21:03:36 +0100 Subject: [PATCH] chess.js: Much faster disambiguation. --- www/js/chess.js | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/www/js/chess.js b/www/js/chess.js index f274628..9a2d383 100644 --- a/www/js/chess.js +++ b/www/js/chess.js @@ -708,6 +708,10 @@ var Chess = function(fen) { } } + return possibly_filter_moves(moves, us, legal); + } + + function possibly_filter_moves(moves, us, legal) { /* return all pseudo-legal moves (this includes moves that allow the king * to be captured) */ @@ -1114,12 +1118,17 @@ var Chess = function(fen) { /* this function is used to uniquely identify ambiguous moves */ function get_disambiguator(move, sloppy) { - var moves = generate_moves({legal: !sloppy}); - var from = move.from; var to = move.to; var piece = move.piece; + if (piece === 'p' || piece === 'k') { + // Pawn or king moves are never ambiguous. + return ''; + } + + let moves = find_attacking_moves(move.to, piece, move.color, sloppy); + var ambiguities = 0; var same_rank = 0; var same_file = 0; @@ -1167,6 +1176,41 @@ var Chess = function(fen) { return ''; } + // Find all moves featuring the given piece attacking the given square + // (using symmetry of all non-pawn-or-castle moves, we simply generate + // moves backwards). Does not support kings or pawns. Assumes there's + // not already a piece of our own color on the destination square. + function find_attacking_moves(to, piece, us, sloppy) { + let moves = []; + + function add_move(board, moves, from, to, flags, rook_sq) { + moves.push(build_move(board, from, to, flags, undefined, rook_sq)); + } + for (let offset of PIECE_OFFSETS[piece]) { + var square = to; + + while (true) { + square += offset; + if (square & 0x88) break; + + if (board[square] != null) { + if (board[square].color !== us) break; + if (board[to] == null) { + add_move(board, moves, square, to, BITS.NORMAL); + } else { + add_move(board, moves, square, to, BITS.CAPTURE); + } + break; + } + + /* break if knight */ + if (piece === 'n') break; + } + } + + return possibly_filter_moves(moves, us, !sloppy); + } + function ascii() { var s = ' +------------------------+\n'; for (var i = SQUARES.a8; i <= SQUARES.h1; i++) { -- 2.39.5