#!/usr/bin/perl # # Reverse of convert_epd.pl: turns typhoon's setboard/solution|avoid/ # id/go script-format suites back into real EPD, one record per line, # now that the engine can read EPD directly (`epd ` -- see # ParseEpdRecord in fen.c, EpdCommand in script.c). Written to retire # the setboard/solution/go intermediate format for suites that are # just EPD underneath, so there's one suite format instead of two. # # Mirrors ScriptCommand's own state machine: track the most recent # setboard/id/solution/avoid seen and emit one EPD record per "go", # ignoring any other command in between (sd, st, easy, version, # quit, ...) -- those belong to scripts that aren't really EPD suites # (bench.ep_, trial.ep_) and shouldn't be fed to this converter. use strict; use warnings; my $fen; my $id; my @sol; my @avoid; while (my $line = <>) { chomp $line; $line =~ s/\r$//; if ($line =~ /^\s*setboard\s+(.*?)\s*$/i) { $fen = $1; } elsif ($line =~ /^\s*id\s+(.*?)\s*$/i) { $id = $1; $id =~ s/^"|"$//g; } elsif ($line =~ /^\s*solution\s+(.*?)\s*$/i) { push @sol, split(/\s+/, $1); } elsif ($line =~ /^\s*avoid\s+(.*?)\s*$/i) { push @avoid, split(/\s+/, $1); } elsif ($line =~ /^\s*go\s*$/i) { if (defined($fen) && (@sol || @avoid)) { my ($opcode, @moves) = @sol ? ('bm', @sol) : ('am', @avoid); print "$fen $opcode " . join(' ', @moves) . ';'; print " id \"$id\";" if defined $id; print "\n"; } else { warn "ep_to_epd.pl: skipping a 'go' with no fen/solution " . "in scope (non-suite script line?)\n"; } @sol = (); @avoid = (); $id = undef; # $fen deliberately survives a record with no solution/avoid # (mirrors ScriptCommand: a bare setboard+go with no solution # just plays a move, it doesn't reset anything) -- but since we # skip printing when there's no solution anyway, this only # matters for a same-fen "go" that follows one with a solution, # which none of the real suites in tests/ do. } # everything else (sd, st, easy, version, quit, ...) ignored. }