Chess4p

 view release on metacpan or  search on metacpan

lib/Chess4p/Pgn/Reader.pm  view on Meta::CPAN

package Chess4p::Pgn::Reader;

use v5.36;

use utf8;

use Chess4p;

use Exporter 'import';

our @EXPORT_OK = qw(
    &read_game
);

our $_debug = 0;

my $NAG_GOOD_MOVE = 1;
my $NAG_MISTAKE = 2;
my $NAG_BRILLIANT_MOVE = 3;
my $NAG_BLUNDER = 4;
my $NAG_SPECULATIVE_MOVE = 5;
my $NAG_DUBIOUS_MOVE = 6;

my $move_text_rx = qr'
                       [NBKRQ]?[a-h]?[1-8]?[\-x]?[a-h][1-8](?:=?[nbrqkNBRQK])?
                     | -- | Z0 | 0000 | @@@@
                     | O-O(?:-O)?
                     | 0-0(?:-0)?    
                     | [?!]{1,2}
                     | \* | 1-0 | 0-1 | 1/2-1/2
                     | \$[0-9]+    # NAG
                     | \{.*        # Game comment    
                     | ;.*         # PGN file comment    
                     | \(          # Variation start
                     | \)          # Variation end
                     'xo;

my $tag_rx = qr'^\[([A-Za-z0-9][A-Za-z0-9_+#=:-]*)\s+\"([^\r]*)\"\]\s*$'o;

my $skip_move_text_rx = qr';|\{|\}'o;

  
sub read_game {
    my ($fh, $visitor) = @_;

    my @errors;

    my $line = <$fh>;

    # Remove BOM if needed
    $line =~ s/^\x{FEFF}// if defined $line;

    say "10---------> $line" if $_debug;

    # Ignore leading empty lines and comments.
    while (defined $line && $line =~/^[;%]?\s*$/) {
        $line = <$fh>; #  Use of uninitialized value $line in pattern match (m//) at lib/Chess4p/Pgn/Reader.pm line 53,
    }

    return undef unless $line;

    say "20---------> $line" if $_debug;

    my $found_game = 0;
    my $skipping_game = 0;
    my @board_stack = ();
    my $consecutive_empty_lines = 0;
    my $fen;

    # Loop to collect game headers
    while ($line) {

        say "30---------> $line" if $_debug;
        
        # Ignore comments.
        if ($line =~/^[;%]/) {
            $line = <$fh>;
            next;
        }
        
        # Ignore up to one consecutive empty line between headers.
        if ($consecutive_empty_lines < 1 && $line =~/^\s*$/) {
            $consecutive_empty_lines++;
            $line = <$fh>;
            next;
        }
        
        # First token of the game.
        unless ($found_game) {
            $found_game = 1;
            $skipping_game = $visitor->begin_game();



( run in 1.805 second using v1.01-cache-2.11-cpan-5735350b133 )