Closed HBiSoft closed 5 years ago
Hi @HBiSoft , Yes you can try the follow:
@Test
public void testWalkingPgn() throws Exception {
PgnHolder pgn = new PgnHolder("src/test/resources/oo.pgn");
pgn.loadPgn();
// iterate through the games or get the game you want to look at
for (Game game: pgn.getGame()) {
game.loadMoveText(); // lazily load the game you want to look at (in case we are just listing the games we don't need that)
game.setCurrentMoveList(game.getHalfMoves()); // set the game list for "navigation"
game.setBoard(new Board()); "set the board for associating the positions"
game.gotoFirst(); // got to first position in the board
System.out.println(game.getBoard().getFen());
while (!game.isEndOfMoveList()) { // iterate till the end of the move list
game.gotoNext(); // go to next position in the move list
System.out.println(game.getBoard().getFen()); // print the FEN of the current position
System.out.println(" Move (" + game.getPosition() + ") = " + game.getCurrentMoveList().get(game.getPosition()).getSan() ); // print the current move in SAN format
MoveList partialMoves = new MoveList();
partialMoves.addAll(game.getCurrentMoveList().subList(0, game.getPosition() + 1));
System.out.println(" Partial movelist: " + partialMoves.toSan()); // prints the current move list
}
}
}
you also have the methods gotoPrior
and gotoLast
.
Awsome, thank you very much.
@bhlangonijr I only have one more issue, if you can please help me.
The problem I have is that partialMoves.toSan()
will return, for example e4 e6
. The next time I press Next
it will return, for example e6 e4 d4 d5
and so on.
What I'm trying to achieve is to get the next move only for example if I press Next
I want to get e6
then e4
and so on.
Is that possible?
This is what I currently have:
MoveList partialMoves = new MoveList();
partialMoves.addAll(refGame.getCurrentMoveList().subList(0, refGame.getPosition()));
String nextMove = partialMoves.toSan();
Each time I call the above the next 2 moves will be added to nextMove
, instead of only giving me the next move only.
Hi @HBiSoft, The code below should behave exactly as you expect:
@Test
public void testWalkingThorughPgn() throws Exception {
PgnHolder pgn = new PgnHolder("src/test/resources/oo.pgn");
pgn.loadPgn();
for (Game game: pgn.getGame()) {
game.loadMoveText();
game.setCurrentMoveList(game.getHalfMoves());
game.setBoard(new Board());
game.gotoFirst();
System.out.println(game.getBoard().getFen());
System.out.println("First Move: " + game.getCurrentMoveList().get(0).getSan());
while (!game.isEndOfMoveList()) {
game.gotoNext();
MoveList partialMoves = new MoveList();
partialMoves.addAll(game.getCurrentMoveList().subList(0, game.getPosition() ));
System.out.println("Movelist: " + partialMoves.toSan() + " next Move: " + game.getCurrentMoveList().get(game.getPosition()).getSan());
}
}
}
For this PGN:
[Site "CCRL"]
[Date "2018.10.19"]
[Round "1"]
[White "CM10th Default"]
[Black "Fritz 9"]
[Result "1-0"]
[PlyCount "0"]
[TimeControl "?"]
[ECO "A13"]
[WhiteElo "2633"]
[BlackElo "2743"]
1. Nf3 d5 2. g3 e6 3. c4 d4 4. e3 Nc6 5. exd4 Nxd4 6. Bg2 Nh6 7. O-O Nhf5 8. d3 Be7
9. Nxd4 Nxd4 10. Nd2 h5 11. Nb3 h4 12. Bd2 hxg3 13. hxg3 Bf6 14. Bc3 c6 15. Re1 Rh6
16. Re4 Nf5 17. Bxf6 Qxf6 18. Qd2 Nd6 19. Rf4 Qe7 20. c5 Nf5 21. Re1 Qg5 22. Qa5
Rh8 23. Re5 g6 24. Re1 Qd8 25. Qc3 Rh7 26. Rg4 Ne7 27. Ree4 Nd5 28. Qc1 Qf6 29. Rh4
Rxh4 30. Rxh4 Bd7 31. Nd2 1-0
It'll give me:
First Move: Nf3
Movelist: Nf3 next Move: d5
Movelist: Nf3 d5 next Move: g3
Movelist: Nf3 d5 g3 next Move: e6
Movelist: Nf3 d5 g3 e6 next Move: c4
Movelist: Nf3 d5 g3 e6 c4 next Move: d4
Movelist: Nf3 d5 g3 e6 c4 d4 next Move: e3
Movelist: Nf3 d5 g3 e6 c4 d4 e3 next Move: Nc6
Movelist: Nf3 d5 g3 e6 c4 d4 e3 Nc6 next Move: exd4
Movelist: Nf3 d5 g3 e6 c4 d4 e3 Nc6 exd4 next Move: Nxd4
Movelist: Nf3 d5 g3 e6 c4 d4 e3 Nc6 exd4 Nxd4 next Move: Bg2
Movelist: Nf3 d5 g3 e6 c4 d4 e3 Nc6 exd4 Nxd4 Bg2 next Move: Nh6
Movelist: Nf3 d5 g3 e6 c4 d4 e3 Nc6 exd4 Nxd4 Bg2 Nh6 next Move: O-O
Movelist: Nf3 d5 g3 e6 c4 d4 e3 Nc6 exd4 Nxd4 Bg2 Nh6 O-O next Move: Nhf5
Movelist: Nf3 d5 g3 e6 c4 d4 e3 Nc6 exd4 Nxd4 Bg2 Nh6 O-O Nhf5 next Move: d3
Movelist: Nf3 d5 g3 e6 c4 d4 e3 Nc6 exd4 Nxd4 Bg2 Nh6 O-O Nhf5 d3 next Move: Be7
Movelist: Nf3 d5 g3 e6 c4 d4 e3 Nc6 exd4 Nxd4 Bg2 Nh6 O-O Nhf5 d3 Be7 next Move: Nxd4
Movelist: Nf3 d5 g3 e6 c4 d4 e3 Nc6 exd4 Nxd4 Bg2 Nh6 O-O Nhf5 d3 Be7 Nxd4 next Move: Nxd4
Movelist: Nf3 d5 g3 e6 c4 d4 e3 Nc6 exd4 Nxd4 Bg2 Nh6 O-O Nhf5 d3 Be7 Nxd4 Nxd4 next Move: Nd2
...
Maybe you somehow are calling gotoNext
twice?
@bhlangonijr Silly me, I was calling gotoNext
twice.
" next Move: " + game.getCurrentMoveList().get(game.getPosition()).getSan()
also helped a lot.
Thank you very much for taking the time to answer.
@HBiSoft cool, let me know if I can help you in any issue
@bhlangonijr I have one last issue, I promise this is the last one lol.
Currently I get the next position back as, for example fxe5
or Nc6
, but when I make a move, it requires me to call the following:
board.doMove(new Move(Square.E2, Square.E4));
How would I then translate fxe5
to a square?
Square.fromValue(someStrring)
, but it also requires a square like G8
..@HBiSoft The move list is stored in a long algebraic format consisting of the two full coordinates. What you have there fxe5
is the SAN format and depends on the current state of the chessboard to mean something. My point is you should try to store the long algebraic format for each move so that you can restore it in the chessboard easily at any point in time. Just don't use the move#toSan()
for storing the move. move#toString
should give you the long algebraic format. If you need the SAN notation again you can easily convert the move to it afterwards.
You can ask things whenever, I am not bothered because of that. :)
@bhlangonijr Ok great that makes sense, so instead of getting the actual move that was played, I should get the "start" and "end" squares.
I did the following to get the above:
Game.getCurrentMoveList().get(refGame.getPosition()).toString()
This returns e4e5
, I guess I can then convert that to uppercase and split the string to get 2 separate values, then set that to Move
, like this:
String moveSquares = game.getCurrentMoveList().get(game.getPosition()).toString();
String startingSquare = moveSquares.substring(0,2).toUpperCase(); //this returns E4
String endingSquare= moveSquares.substring(Math.max(moveSquares.length() - 2, 0)).toUpperCase(); //this returns E5
board.doMove(new Move(Square.fromValue(startingSquare), Square.fromValue(endingSquare)));
@HBiSoft I was not really sure of what you were trying to achieve. But if you just want to unmake one move you just call Move move = board.undoMove();
. It'll retrieve the last move made and undo it. It can be called many times for as many moves that were made until you get to the start position.
Hi, is it possible to get individual positions from a pgn file?
For example, when pressing "next" I would like to get the next move and when pressing "previous" I would like to get the previous move.