enzomanuelmangano / react-native-chessboard

A lightweight, simple, and high-performing chessboard for React Native
MIT License
59 stars 17 forks source link

allow same .move() interface as Chess.js provides (allow SAN) #5

Open artiphishle opened 1 year ago

artiphishle commented 1 year ago

Hi

first thanks for the great work.

As you're using Chess.js bts could you please enable the full .move() api (including SAN moves)

.move('e4') as a first move equals .move({ from: 'e2', to: 'e4' })

SAN is just more common for chess players, and the way I (and many) store the games/moves in the db. Conversion also requires to always keep track of the board (e.g. 'e4' could be from 'e2' or from 'e3') so it feels like an additional redundant work, as Chess.js already provides all the possibilities. (Imagine to programmatically play down a PGN file, every move has to be converted while keeping track of the board at all time)

Thank you!

og-nav commented 1 year ago

not the owner, but I've looked around and the { from, to } stuff is used for more than just making the move (for example, it's used for highlighting squares after a move, promotion, etc).

Here's what I did for loading pgns/fens:

  1. import files:
    import React, { useRef, useState } from 'react';
    import { Chess } from 'chess.js';
    import { ChessboardRef } from 'react-native-chessboard';
    const _ = require('lodash');
  2. initialize chess object and chessboard ref
    const [chess, setChess] = useState(new Chess()); // include fen from db if needed
    const chessboardRef = useRef<ChessboardRef>(null);
  3. Update external chess object for move
    // get move from db
    const gameCopy = _.cloneDeep(chess);
    gameCopy.move(move); // in SAN notation
    setChess(gameCopy);
  4. Update internal chess object / make move programmatically
    const lastMove = chess.history({ verbose: true }).slice(-1)[0]; // ensure that this is not called without any moves played
    (async () => {
    await chessboardRef.current?.move({ from: lastMove.from, to: lastMove.to });
    })();

for keeping track of moves played on the board (and then updating the external chess.js object), I went through his code and added the 'history' option to the chessboard state. check the src/helpers/get-chessboard-state.ts file in my fork of this repo for my implementation of it. then you can use onMove

return (
...
<Chessboard ref={chessboardRef} onMove={({ state }) => {
    const history = state.history;
    ...
}} />
)

then you can do the same thing of getting the last move and then making the move in your external chess.js object.

this is probably not the answer you're looking for, but I think it's the simplest way of going about it. I don't think you will be able to get around the { from, to } without a decent amount of work. just my thoughts.

artiphishle commented 1 year ago

FEN is supported btw, you could also reset initial board position by FEN. Point is, whatever used for internal board control (from, to) should not depend on what the board interface can support. You could easily allow SAN and behind the scene translate it to internal (from, to) format.

The chessboard interface (every chessboard interface in the world) should be able to accept SAN (most used chess move format), that easy :)

Obviously I'm going to have my own game running, whether that's made by chess.js or my own implementation, thanks for pointing that out for clarification. Point is, conversion from SAN > from,to should be happening in the board, I don't care how the board is moving or rendering, I just expect SAN as a default provided by the board api.

enzomanuelmangano commented 1 year ago

Hi @scha-ch thank you very much for the feedback! Actually I think that would be a great feature to add :) Stay tuned with next updates!