Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help with PGN to FEN strings with move list #1120

Open
atenonai opened this issue Nov 24, 2024 · 1 comment
Open

Help with PGN to FEN strings with move list #1120

atenonai opened this issue Nov 24, 2024 · 1 comment

Comments

@atenonai
Copy link

I would like to achieve the following:

  1. Use a PGN-file as input.
  2. Output individual FEN strings for each position from a chosen perspective, including variations. The FEN position should be before the opposite color made their move.
  3. Include a move list after the FEN string (the first move would be the opposite color, and the second move would be the move from the chosen perspective).
  4. If any moves had annotations (comments/[%csl ...]/[%cal ...]) those should be preserved in the move list as well.

Example:

With the following PGN as input, and black as the chosen perspective…

[Event "?"]
[Site "?"]
[Date "????.??.??"]
[Round "?"]
[White "?"]
[Black "?"]
[Result "*"]

1. e4 c5 { Sicilian } { [%csl Gd4][%cal Gc5d4] } 2. Nf3 (2. Nc3 { Closed Sicilian } 2... d6) 2... d6 *

…the desired output would be:

[FEN "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"]
1. e4 c5 { Sicilian } { [%csl Gd4][%cal Gc5d4] }

[FEN "rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 2"]
2. Nf3 d6

[FEN "rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 2"]
2. Nc3 { Closed Sicilian } 2... d6

I hope that all made sense.

Is this possible? I would be grateful for any pointers on how to achieve it.

@atenonai
Copy link
Author

atenonai commented Nov 27, 2024

I figured out the first parts!

How can I include not only moves but also the move numbers and comments/annotations from the PGN? If anyone could provide some pointers that would be great.

import chess
import chess.pgn

pgn_file = '/path'
repertoire_color = 'black'

if repertoire_color == 'black':
    setup_positions = chess.WHITE  # FEN positions will be before opponents move
elif repertoire_color == 'white':
    setup_positions = chess.BLACK  # FEN positions will be before opponents move

with open(pgn_file) as pgn:
    parsed_pgn = chess.pgn.read_game(pgn)

def extract_positions(node, color):
    if node.board().turn == color:
        fen = node.board().fen()
        
        if node.variations:
            # Get opponent move
            for variation in node.variations:
                opponent_move = variation.move
                # Convert move to algebraic notation
                algebraic_opponent_move = node.board().san(opponent_move)
                
                if variation.variations:
                # For each found move, check if there's a response in the repertoire
                    response_move = variation.variations[0].move
                    if response_move:
                    # Convert move to algebraic notation
                        algebraic_response_move = variation.board().san(response_move)
                        
                        # Print the position and move pair
                        print(f'[FEN "{fen}"]\n{algebraic_opponent_move} {algebraic_response_move}\n')
    
    # Recursively process nodes to extract all positions (both main line and sidelines)
    for variation in node.variations:
        extract_positions(variation, color)

extract_positions(parsed_pgn, setup_positions)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant