mliebelt / pgn-viewer

Simple PGN viewer with the necessary features to display chess games
GNU General Public License v3.0
161 stars 44 forks source link

How to get current move?How to get editted board pgn data?. #266

Open karthi6556 opened 3 years ago

karthi6556 commented 3 years ago

In Reactjs.There is anything like onMove() to capture the current move.Then there is anything to get editted pgn moves(whole pgn string).

mliebelt commented 3 years ago

Could you elaborate a little bit your context? So you have the viewer running in a browser, and want to do what? The tool at the moment is mostly for being used by a user, not by controlled by a steering application. But there are ways to do something similar:

The following screenshot shows that example in a browser, with developer tools open.

  1. section: Made the moves e4, e5, Nf3.
  2. section: Printed out the current moves

image

I hope that answers your question.

karthi6556 commented 3 years ago

Hi, This is the code.I implemented in reactjs. const boardId = "pgn-board"; const [board, setBoard] = useState({});

useEffect(() => {
    let mainBoard = pgnEdit(boardId,
    {
        pgn: "1. e4 e5 ( 1... c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6",
        //position: 'start',
        //startPlay: '',
        timerTime: '1',
        //locale: 'pl',
        startPlay: 1,
        showResult: true,
        boardSize: '520',
        showFen: false,
        pieceStyle: 'maya',
        width: '100%',
        movesWidth: '300px',
        theme: 'green',
        mode: 'edit',
        layout: 'left',
        coordsFactor: 0.2,
        coordsInner: false,
        //orientation: 'black',
        movesHeight: '400px',
        //showCoords: false,
        //hideMovesBefore: true,
        notation: 'long', 
        //notationLayout: 'list'
    })
    console.log(mainBoard)
    setBoard(mainBoard)
},[])

return(
    <Row>
        <Col>
            <div id={boardId}></div>
        </Col>
    </Row>
);

Here console.log prints this object

base:
{
  board: null
  chess: {WHITE: "w", BLACK: "b", PAWN: "p", KNIGHT: "n", BISHOP: "b", …}
  generateBoard: ƒ ()
  generateHTML: ƒ ()
  generateMoves: ƒ ()
  getPgn: ƒ ()
  manualMove: ƒ (M)
  onSnapEnd: ƒ x(M, A, g)
  resizeLayout: ƒ Q()
}
board:
{
  cancelMove: cancelMove() { t.render(M => {…}
  cancelPredrop: ƒ cancelPredrop()
  cancelPremove: ƒ cancelPremove()
  destroy: ƒ destroy()
  dragNewPiece: ƒ dragNewPiece(A, N, g)
  explode: ƒ explode(A)
  getFen: () => I.write(M.pieces)
  getKeyAtDomPos: A => g.getKeyAtDomPos(A, g.whitePov(M), M.dom.bounds())
  move: move(A, N) { t.anim(M => {…}
  newPiece: newPiece(A, N) { t.anim(M => {…}
  playPredrop: ƒ playPredrop(A)
  playPremove: ƒ playPremove()
  redrawAll: ƒ e()
  selectSquare: selectSquare(A, N) { A ? t.anim(M => {…}
  set: set(A) { A.orientation && A.orientation !== M.orientation && N(), (A.fen ? t.anim : t.render)(M => {…}
  setAutoShapes: setAutoShapes(A) { t.render(M => {…}
  setPieces: setPieces(A) { t.anim(M => {…}
  setShapes: setShapes(A) { t.render(M => {…}
  state: {pieces: Map(32), orientation: "white", turnColor: "white", coordinates: true, autoCastle: true, …}
  stop: stop() { t.render(M => {…}
  toggleOrientation: ƒ N()
}

But In reactjs I dont know to call the above functions such as base.manualMove(), board.move(), board.getFen(). I need to store the current position it can be viewed to multiple users on moving a piece through websocket. I had checked above references whichever you mentioned, but all are in javascript.Basically I dont know to implement in reactjs. I want to know right way to do that in reactjs.

mliebelt commented 3 years ago

I don't have too much experience in React.js, but from my understanding, you have the full Javascript possibilities at your disposal. That means, you have to find a solution how to bind the mainBoard, so that you are later able to use Javascript functions on it.

Your snippet shows, how the board is constructed, but how will it then be used later? You mention websockets, but on the retrieving end, it should be possible to

Is there any source of you available in GitHub, so I would understand what and how you are trying to reach something? Even a simple description like the following would help:

  1. I start the application and the websocket.
  2. I start the server part of websocket.
  3. The server sends the message XYZ to the client.
  4. The client reacts on it by ABC.

I think in 4, you should be able to say: When I get a SAN move, I am able to send that to the PgnViewerJS.

See https://www.merixstudio.com/blog/websockets-how-it-works-and-how-use-it/ that explains how to use websockets. On the client side (the browser), there must be some Javascript code that gets a request, and reacts on it.

karthi6556 commented 3 years ago

For example see below code,

onDrop = ({ sourceSquare, targetSquare }) => {
    if(this.game.turn() != this.state.turn)
    {
      return false;
    }
    // see if the move is legal
    let move = this.game.move({
      from: sourceSquare,
      to: targetSquare,
      promotion: "q" // always promote to a queen for example simplicity
    });

    // illegal move
    if (move === null) return;
    socket.emit('playFen',this.state.roomId,this.game.fen())
    this.setState(({ history, pieceSquare }) => ({
      fen: this.game.fen(),
      history: this.game.history({ verbose: true }),
      squareStyles: squareStyling({ pieceSquare, history })
    }));
  };

Above code refers chessboardjs in reactjs (chessboardjsx). In this socket.emit('playFen',this.state.roomId,this.game.fen()) is the code which sents to socket.io server where this move will be updated in all clients board. So template will be like this to call onDrop(), <Chessboard onDrop={onDrop} . I understood you mentioned manualMove(), but how to trigger that function whenever position changes.Is there any event handlers to handle this like above example. pgnEdit(boardId, { pgn: "1. e4 e5 ( 1... c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6",}) In config Can I add any eventhandlers?.

mliebelt commented 3 years ago

So once again: your goal is to have many boards following one game played by someone. The PgnViewerJS is "only" a client gui, that allows to play moves on a board. Currently, there is no clear defined API, and there are no event notifications on changes.

There are already tickets addressing that: #175 or #176 but I have not done that. You could help in defining what your need is, but not by giving me example code, but by explaining what you want to do:

It is not at all obvious what could be useful. You said e.g. that you need the current position. That could be added to the list then as well.

So again: who is playing, where do the moves come from, should the board only replay those moves or allow active ones themselves, ...? I don't know all that.

karthi6556 commented 3 years ago

Ok I will explain the scenario. I have one coach and many students.They will be connected through same room with unique roomId. Now Coach will be prepared some pgn to take a class to the students whoever logged into the same room. Now Coach will use cursors (plays the move either through arrow buttons or click on pgn moves) immediately student boards will be changed.Coach may use arrows as markers. So,Whenever coach moves it will be passed through socket client(it works in chessboardjsx). How to do this here? I am trying to find a way like, whenever moves changes in his board I want current Position.So that I will send through socket client or else I can store in realtime databases. So help me to find out this.In reactjs I am trying to do this, because you have implemented in reactjs too.

Bebul commented 2 years ago

https://github.com/mliebelt/PgnViewerJS/blob/750b6724fe0d46f4f46bd8c9ab5ebd2f6c77d0e5/modules/pgn-viewer/src/pgnvjs.js#L1270-L1281

@mliebelt comment: There are already tickets addressing that: #175 or #176 but I have not done that. You could help in defining what your need is, but not by giving me example code, but by explaining what you want to do

Yes! I think it would be very handy for more tasks like Stockfish, PgnPuzzle, Opening Explorer, using PgnViewerJS as front-end. I will try some experiments soon and explain myself after. Sorry now for somewhat confused comments.

mliebelt commented 2 years ago

I have started a wiki page, to start working on the API: https://github.com/mliebelt/PgnViewerJS/wiki/API-and-Callbacks-for-reader-and-viewer

Feel free to add here whatever you want to.

Bebul commented 2 years ago

One optics to think about API is considering running Stockfish evaluation of current position. So nobody wants to ask again and again about the current board position, but rather get notified about change of the board, which can happen from many possible reasons, like doing move by dragging a piece, clicking backward / forward / end / begin button or even replay the game button, by clicking to the move in the pgn list etc. When board changes, there should come some notification. From the engine evaluation I also think the current line would be super to know, when being in some variant, being able to get what is the line from begin to end, which can also start with FEN.

It can maybe help to think about API in this perspective, like imagining someone to do the Engine evaluation as addon or plugin of smart PgnViewerJS.