convert UCI output to SAN for html project

Discussion of chess software programming and technical issues.

Moderator: Ras

Player_one
Posts: 5
Joined: Thu Aug 19, 2021 9:20 pm
Full name: Gary Gauthier

convert UCI output to SAN for html project

Post by Player_one »

I am having difficulty converting engine output to SAN. I sometimes hack the engine code but there has to be a one shot solution so I don't have to doctor individual engines. (from e1g1 b8c6 to O-O Nc6)

The reason I need code to do the conversion is that I am developing my own interface. I use chess.js, by Jeff Hlywa which I believe can do the conversion but my coding skills are limited and don't allow me to solve this particular problem without some assistance.


I appreciate any help or suggestions.

Player_one
User avatar
hgm
Posts: 28353
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: convert UCI output to SAN for html project

Post by hgm »

To generate SAN you have to keep track of the board position, and to know how the pieces can move. If you really want to do it 'by the book', and avoid generating redundant disambiguators in the case where one of the possible moves to the destination would put its own King in check, you even have to test moves for legality. How you can best do this depends on the efficiency that is required; for generating SAN that must be read by a human efficiency probably plays no role at all, so you would go for the simplest solution.

I happen to have a SAN generator in JavaScript, as part of the Interactive Diagram. But it doesn't pay attention to legality of moves (because some chess variants do not have a checking rule, and leaving your King in check is perfectly legal, albeit stupid). So it is based on a pseudo-legal move generator. It is the function ToSan() in the file at https://www.chessvariants.com/membergra ... s/betza.js . The function might be a bit more complex than you need, because it can also handle double or hit-and-run capture (like Lxe5-d4).
Player_one
Posts: 5
Joined: Thu Aug 19, 2021 9:20 pm
Full name: Gary Gauthier

Re: convert UCI output to SAN for html project

Post by Player_one »

Thanks for your response and sharing the code. I will have to go through it to understand how I can incorporate all the variables. As far as validation, it is a secondary issue for my purposes as the code will only be used to parse engine output from high-quality engines.
User avatar
hgm
Posts: 28353
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: convert UCI output to SAN for html project

Post by hgm »

True, you won't have to validate the moves. But the problem I was referring to is than when you have (for example) Knights at g3 and c3, and play c3e4, you must know whether to write Nce4, or just Ne4 because the Knight on g5 was pinned to its King. So you must be able to test whether the alternative move is legal. My code doesn't do that, and would always write Nce4 irrespective of wheter the Knight in the g-file can move.

You would also need a checktest when you want to append a + to checking moves.

P.S. - You should not try to understand the function GenPseudoMoves(), as it is very general, which makes it far more complex than anything you would need for orthodox chess. All you have to know is that it generates all pseudo-legal moves of the piece on the given square, and when one of the destination squares has the coordinates (sanX, sanY) it sets the lowest bit of the global variable san. The trick that I use with sanStart is that when the moved piece could not reach its destination (i.e. the given move was not even pseudo-legal), the lowest bit of san is already set before you try if any other piece of the same type can reach the destination, so that it will always try to disambiguate if there is such a piece. (When there only is a single piece of the relevant type, there never is a need to disambiguate, even if the move is not pseudo-legal.)
Player_one
Posts: 5
Joined: Thu Aug 19, 2021 9:20 pm
Full name: Gary Gauthier

convert UCI output to SAN for html project

Post by Player_one »

Using chess.js* the code below converts engine principal variations into san format.
Shoutout to https://github.com/tennis-aa for drafting the code.

*source: https://github.com/jhlywa/chess.js

Code: Select all

function pvToSan(pv) {
  let moves = pv;
  let movesmade = 0;
  let sanvariation = [];
  for (let i=0; i<moves.length; ++i) {
    let move = game.move({ from: moves[i].slice(0,2), to: moves[i].slice(2,4), promotion: moves[i].length == 5 ? moves[i].slice(4) : "" });
    if (move == null) break;
    ++movesmade;
    sanvariation.push(move.san);
  }
  for (let i=0; i<movesmade; ++i) {
    game.undo();
  }
  
san = sanvariation.join(' ');
console.log(san)
}