File Coverage

blib/lib/Chess/PGN/EPD.pm
Criterion Covered Total %
statement 25 565 4.4
branch 1 424 0.2
condition 0 72 0.0
subroutine 6 28 21.4
pod 9 17 52.9
total 41 1106 3.7


line stmt bran cond sub pod time code
1             package Chess::PGN::EPD;
2            
3 10     10   2200982 use strict;
  10         31  
  10         3335  
4 10     10   71 use warnings;
  10         25  
  10         467  
5 10     10   26432 use Chess::PGN::Moves;
  10         138095  
  10         4445  
6 10     10   16512 use Storable qw( retrieve );
  10         49977  
  10         1141  
7 10     10   15856 use Try::Tiny qw( try catch );
  10         20098  
  10         119025  
8            
9             require Exporter;
10            
11             my ( $hECO, $hNIC, $hOpening );
12             my %hash = (
13             ECO => \$hECO,
14             NIC => \$hNIC,
15             Opening => \$hOpening
16             );
17            
18             my $ECO_path;
19             my $NIC_path;
20             my $Opening_path;
21            
22             ($ECO_path,$NIC_path,$Opening_path) = GetPaths('Chess::PGN::EPD');
23            
24             try {
25             $hECO = retrieve($ECO_path);
26             } catch {
27             print "Couldn't open $ECO_path : $!";
28             exit;
29             };
30             try {
31             $hNIC = retrieve($NIC_path);
32             } catch {
33             print "Couldn't open $NIC_path : $!";
34             exit;
35             };
36             try {
37             $hOpening = retrieve($Opening_path);
38             } catch {
39             print "Couldn't open $Opening_path : $!";
40             exit;
41             };
42            
43             our @ISA = qw(Exporter);
44             our @EXPORT = qw(
45             &epdcode
46             &epdset
47             &epdfromto
48             &epdstr
49             &epdlist
50             &epdgetboard
51             &epdTaxonomy
52             &psquares
53             %font2map
54             );
55             our $VERSION = '0.31';
56            
57             our %font2map = (
58             'Chess Cases' => 'leschemelle',
59             'Chess Adventurer' => 'marroquin',
60             'Chess Alfonso-X' => 'marroquin',
61             'Chess Alpha' => 'bentzen1',
62             'Chess Berlin' => 'bentzen2',
63             'Chess Condal' => 'marroquin',
64             'Chess Harlequin' => 'marroquin',
65             'Chess Kingdom' => 'marroquin',
66             'Chess Leipzig' => 'marroquin',
67             'Chess Line' => 'marroquin',
68             'Chess Lucena' => 'marroquin',
69             'Chess Magnetic' => 'marroquin',
70             'Chess Mark' => 'marroquin',
71             'Chess Marroquin' => 'marroquin',
72             'Chess Maya' => 'marroquin',
73             'Chess Mediaeval' => 'marroquin',
74             'Chess Merida' => 'marroquin',
75             'Chess Millennia' => 'marroquin',
76             'Chess Miscel' => 'marroquin',
77             'Chess Montreal' => 'katch',
78             'Chess Motif' => 'marroquin',
79             'Chess Plain' => 'hickey',
80             'Chess Regular' => 'scott1',
81             'Chess Usual' => 'scott2',
82             'Chess Utrecht' => 'bodlaender',
83             'Tilburg' => 'tilburg',
84             'Traveller Standard V3' => 'cowderoy',
85             );
86            
87             my %board = qw(
88             a1 R a2 P a7 p a8 r
89             b1 N b2 P b7 p b8 n
90             c1 B c2 P c7 p c8 b
91             d1 Q d2 P d7 p d8 q
92             e1 K e2 P e7 p e8 k
93             f1 B f2 P f7 p f8 b
94             g1 N g2 P g7 p g8 n
95             h1 R h2 P h7 p h8 r
96             );
97             my $Kc = 1;
98             my $Qc = 1;
99             my $kc = 1;
100             my $qc = 1;
101             my $w = 1;
102            
103             my @onwhite = (
104             1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0,
105             1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1,
106             0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1,
107             );
108            
109             my %FontMap = (
110             hicky => {
111             OnBlack => 'OMASTLPNBRQK@',
112             OnWhite => 'omastlpnbrqk:',
113             SingleBox => '12345678',
114             DoubleBox => '!"#$%&\'(',
115             SingleRounded => '[]\^',
116             DoubleRounded => '<>;=/',
117             SingleLeftLegend => 'cdefghij',
118             DoubleLeftLegend => 'CDEFGHIJ',
119             SingleBottomLegend => 'wxyz{|}~',
120             DoubleBottomLegend => ')*+,-./0',
121             },
122             marroquin => {
123             OnBlack => 'OMVTWLPNBRQK+',
124             OnWhite => 'omvtwlpnbrqk ',
125             SingleBox => '12345789',
126             DoubleBox => '!"#$%/()',
127             SingleRounded => 'asdf',
128             DoubleRounded => 'ASDF',
129             SingleLeftLegend => "\300\301\302\303\034\305\306\307",
130             DoubleLeftLegend => "\340\341\342\343\344\345\346\347",
131             SingleBottomLegend => "\310\311\312\313\314\315\316\317",
132             DoubleBottomLegend => "\350\351\352\353\354\355\356\357",
133             },
134             leschemelle => {
135             OnBlack => 'OMVTWLPNBRQK+',
136             OnWhite => 'omvtwlpnbrqk ',
137             SingleBox => '12345789',
138             DoubleBox => '!"#$%/()',
139             SingleRounded => 'asdf',
140             DoubleRounded => 'ASDF',
141             SingleLeftLegend => "\300\301\302\303\034\305\306\307",
142             DoubleLeftLegend => "\340\341\342\343\344\345\346\347",
143             SingleBottomLegend => "\310\311\312\313\314\315\316\317",
144             DoubleBottomLegend => "\350\351\352\353\354\355\356\357",
145             },
146             linares => {
147             OnBlack => '0hg41i)HG$!Id',
148             OnWhite => 'pnbrqkPNBRQKw',
149             SingleBox => 'W_W[]W-W',
150             DoubleBox => 'cuC{}vlV',
151             SingleRounded => 'WWWW',
152             DoubleRounded => 'cCvV',
153             SingleLeftLegend => "\332\333\334\335\336\337\340\341",
154             DoubleLeftLegend => '(765&32%',
155             SingleBottomLegend => "\301\302\303\304\305\306\307\310",
156             DoubleBottomLegend => ',./9EFJM',
157             },
158             linares1 => {
159             OnBlack => '0hg41i)HG$!Id',
160             OnWhite => 'pnbrqkPNBRQKw',
161             SingleBox => '>;?:
162             DoubleBox => '>;?:
163             SingleRounded => '>?A@',
164             DoubleRounded => '>?A@',
165             SingleLeftLegend => '::::::::',
166             DoubleLeftLegend => '::::::::',
167             SingleBottomLegend => '========',
168             DoubleBottomLegend => '========',
169             },
170             linares2 => {
171             OnBlack => '0hg41i)HG$!Id',
172             OnWhite => 'pnbrqkPNBRQKw',
173             SingleBox => '^xY|yUz\\',
174             DoubleBox => '^xY|yUz\\',
175             SingleRounded => '^YU\\',
176             DoubleRounded => '^YU\\',
177             SingleLeftLegend => '||||||||',
178             DoubleLeftLegend => '||||||||',
179             SingleBottomLegend => 'zzzzzzzz',
180             DoubleBottomLegend => 'zzzzzzzz',
181             },
182             cowderoy => {
183             OnBlack => '$#!&%"*)\',+(0',
184             OnWhite => 'pnbrqkPNBRQK ',
185             SingleBox => '78946123',
186             DoubleBox => '78946123',
187             SingleRounded => '7913',
188             DoubleRounded => '7913',
189             SingleLeftLegend => '44444444',
190             DoubleLeftLegend => '44444444',
191             SingleBottomLegend => '22222222',
192             DoubleBottomLegend => '22222222',
193             },
194             bentzen1 => {
195             OnBlack => 'OJNTWLPHBRQK+',
196             OnWhite => 'ojntwlphbrqk ',
197             SingleBox => '!"#$%&\'(',
198             DoubleBox => '12345789',
199             SingleRounded => '!#&(',
200             DoubleRounded => '1379',
201             SingleLeftLegend => "\340\341\342\343\344\345\346\347",
202             DoubleLeftLegend => "\300\301\302\303\304\305\306\307",
203             SingleBottomLegend => "\350\351\352\353\354\355\356\357",
204             DoubleBottomLegend => "\310\311\312\313\314\315\316\317",
205             },
206             bentzen2 => {
207             OnBlack => 'OJNTWLPHBRQK+',
208             OnWhite => 'ojntwlphbrqk ',
209             SingleBox => '12345789',
210             DoubleBox => '12345789',
211             SingleRounded => '1379',
212             DoubleRounded => '1379',
213             SingleLeftLegend => '44444444',
214             DoubleLeftLegend => '44444444',
215             SingleBottomLegend => '88888888',
216             DoubleBottomLegend => '88888888',
217             },
218             scott1 => {
219             OnBlack => 'OJNTWLPHBRQK+',
220             OnWhite => 'ojntwlphbrqk*',
221             SingleBox => '(-)/\[_]',
222             DoubleBox => '(-)/\[_]',
223             SingleRounded => '(-)/\[_]',
224             DoubleRounded => '(-)/\[_]',
225             SingleLeftLegend => '////////',
226             DoubleLeftLegend => '////////',
227             SingleBottomLegend => '________',
228             DoubleBottomLegend => '________',
229             },
230             scott2 => {
231             OnBlack => 'OMVTWLPNBRQK+',
232             OnWhite => 'omvtwlpnbrqk ',
233             SingleBox => '12345789',
234             DoubleBox => '!"#$%/()',
235             SingleRounded => 'asdf',
236             DoubleRounded => 'ASDF',
237             SingleLeftLegend => '44444444',
238             DoubleLeftLegend => '$$$$$$$$',
239             SingleBottomLegend => '44444444',
240             DoubleBottomLegend => '$$$$$$$$',
241             },
242             bodlaender => {
243             OnBlack => 'OMVTWLomvtwl/',
244             OnWhite => 'PNBRQKpnbrqk ',
245             SingleBox => '51632748',
246             DoubleBox => '51632748',
247             SingleRounded => '51632748',
248             DoubleRounded => '51632748',
249             SingleLeftLegend => '33333333',
250             DoubleLeftLegend => '33333333',
251             SingleBottomLegend => '44444444',
252             DoubleBottomLegend => '44444444',
253             },
254             katch => {
255             OnBlack => 'OMVTWLPNBRQK/',
256             OnWhite => 'omvtwlpnbrqk ',
257             SingleBox => '12345789',
258             DoubleBox => '12345789',
259             SingleRounded => '12345789',
260             DoubleRounded => '12345789',
261             SingleLeftLegend => '44444444',
262             DoubleLeftLegend => '44444444',
263             SingleBottomLegend => '88888888',
264             DoubleBottomLegend => '88888888',
265             },
266             dummy => {
267             OnBlack => '',
268             OnWhite => '',
269             SingleBox => '',
270             DoubleBox => '',
271             SingleRounded => '',
272             DoubleRounded => '',
273             SingleLeftLegend => '',
274             DoubleLeftLegend => '',
275             SingleBottomLegend => '',
276             DoubleBottomLegend => '',
277             },
278             );
279            
280             my %convertPalView = (
281             'r',
282             '',
283             'n',
284             '',
285             'b',
286             '',
287             'q',
288             '',
289             'k',
290             '',
291             'p',
292             '',
293             'R',
294             '',
295             'N',
296             '',
297             'B',
298             '',
299             'Q',
300             '',
301             'K',
302             '',
303             'P',
304             '',
305             ' ',
306             '',
307             '-',
308             '',
309             );
310            
311             sub epdcode {
312 0     0 1 0 my $key = shift;
313 0         0 my $epd = shift;
314 0         0 my $code;
315 0         0 my $h = ${$hash{$key}};
  0         0  
316            
317 0         0 for ( @{$epd} ) {
  0         0  
318 0         0 $code = $h->{$_}; ## no critic
319 0 0       0 last if $code;
320             }
321 0   0     0 return ( $code or 'Unknown' );
322             }
323            
324             sub epdset {
325 0 0   0 1 0 if ( my $epd = shift ) {
326 0         0 my @array = split( /\/|\s/, $epd );
327 0         0 my $file = '8';
328            
329 0         0 %board = ();
330 0         0 $Kc = 0;
331 0         0 $Qc = 0;
332 0         0 $kc = 0;
333 0         0 $qc = 0;
334 0         0 for ( 0 .. 7 ) {
335 0         0 $array[$_] =~ s/(\d+)/'_' x $1/ge;
  0         0  
336 0         0 my @row = split( '', $array[$_] );
337 0         0 my $rank = 'a';
338 0         0 for my $piece (@row) {
339 0 0       0 $board{"$rank$file"} = $piece if $piece ne '_';
340 0         0 $rank++;
341             }
342 0         0 $file--;
343             }
344 0         0 $w = ( $array[8] eq 'w' );
345 0         0 for ( split( '', $array[9] ) ) {
346 0 0       0 if ( $_ eq 'K' ) {
    0          
    0          
    0          
347 0         0 $Kc = 1;
348             }
349             elsif ( $_ eq 'Q' ) {
350 0         0 $Qc = 1;
351             }
352             elsif ( $_ eq 'k' ) {
353 0         0 $kc = 1;
354             }
355             elsif ( $_ eq 'q' ) {
356 0         0 $qc = 1;
357             }
358             }
359             }
360             else {
361 0         0 %board = qw(
362             a1 R a2 P a7 p a8 r
363             b1 N b2 P b7 p b8 n
364             c1 B c2 P c7 p c8 b
365             d1 Q d2 P d7 p d8 q
366             e1 K e2 P e7 p e8 k
367             f1 B f2 P f7 p f8 b
368             g1 N g2 P g7 p g8 n
369             h1 R h2 P h7 p h8 r
370             );
371 0         0 $w = 1;
372 0         0 $Kc = 1;
373 0         0 $Qc = 1;
374 0         0 $kc = 1;
375 0         0 $qc = 1;
376             }
377 0         0 return;
378             }
379            
380             sub epdstr {
381 0     0 1 0 my %parameters = @_;
382 0 0       0 if ( $parameters{'board'} ) {
383 0         0 my %board;
384 0         0 my $hashref = $parameters{'board'};
385            
386 0         0 for ( keys %$hashref ) {
387 0         0 $board{$_} = $$hashref{$_};
388             }
389 0         0 $parameters{'epd'} = epd( 0, 0, 0, 0, 0, 0, %board );
390             }
391 0         0 my $epd;
392             my $type;
393             try {
394 0     0   0 $epd = $parameters{'epd'};
395             } catch {
396 0     0   0 print "Missing epd parameter: $!\n";
397 0         0 exit;
398 0         0 };
399             try {
400 0     0   0 $type = lc( $parameters{'type'} );
401             } catch {
402 0     0   0 print "Missing type parameter: $!\n";
403 0         0 exit;
404 0         0 };
405 0         0 my ( $border, $corner, $legend ) = ( 'single', 'square', 'no' );
406            
407 0 0       0 $border = lc( $parameters{'border'} ) if exists( $parameters{'border'} );
408 0 0       0 $corner = lc( $parameters{'corner'} ) if exists( $parameters{'corner'} );
409 0 0       0 $legend = lc( $parameters{'legend'} ) if exists( $parameters{'legend'} );
410 0         0 my @array = split( /\/|\s/, $epd );
411 0         0 my @board;
412 0 0       0 if ( $type eq 'diagram' ) {
    0          
    0          
    0          
    0          
413 0         0 for ( 0 .. 7 ) {
414 0         0 $array[$_] =~ s/(\d+)/'_' x $1/ge;
  0         0  
415 0         0 $array[$_] =~
416 0 0 0     0 s/_/(((pos $array[$_]) % 2) xor ($_ % 2)) ? '-' : ' '/ge;
417 0         0 push( @board, 8 - $_ . " " . $array[$_] );
418             }
419 0         0 push( @board, ' abcdefgh' );
420             }
421             elsif ( $type eq 'text' ) {
422 0         0 for ( 0 .. 7 ) {
423 0         0 $array[$_] =~ s/(\d+)/'_' x $1/ge;
  0         0  
424 0         0 $array[$_] =~
425 0 0 0     0 s/_/(((pos $array[$_]) % 2) xor ($_ % 2)) ? '-' : ' '/ge;
426 0         0 push( @board, $array[$_] );
427             }
428             }
429             elsif ( $type eq 'palview' ) {
430 0         0 my @diagram;
431             my $table;
432            
433 0         0 for ( 0 .. 7 ) {
434 0         0 $array[$_] =~ s/(\d+)/'_' x $1/ge;
  0         0  
435 0         0 $array[$_] =~
436 0 0 0     0 s/_/(((pos $array[$_]) % 2) xor ($_ % 2)) ? '-' : ' '/ge;
437 0         0 push( @diagram, $array[$_] );
438             }
439 0         0 for (@diagram) {
440 0         0 for ( split(//) ) {
441 0         0 $table .= $convertPalView{$_};
442             }
443 0         0 $table .= "
";
444 0         0 push( @board, $table );
445 0         0 $table = '';
446             }
447             }
448             elsif ( $type eq 'latex' ) {
449 0         0 push( @board, '\\begin{diagram}' );
450 0         0 push( @board, '\\board' );
451 0         0 for ( 0 .. 7 ) {
452 0         0 $array[$_] =~ s/(\d+)/'_' x $1/ge;
  0         0  
453 0         0 $array[$_] =~
454 0 0 0     0 s/_/(((pos $array[$_]) % 2) xor ($_ % 2)) ? '*' : ' '/ge;
455 0         0 push( @board, '{' . $array[$_] . '}' );
456             }
457 0         0 push( @board, '\\end{diagram}' );
458             }
459             elsif ( $type eq 'tilburg' ) {
460 0         0 for ( 0 .. 7 ) {
461 0         0 $array[$_] =~ s/(\d+)/'_' x $1/ge;
  0         0  
462 0         0 $array[$_] =~
463 0         0 s/([pnbrqkPNBRQK_])/mappiece(pos $array[$_],$_,$1,"\341\345\351\355\361\365\337\343\347\353\357\363
464             \335","\340\344\350\354\360\364\336\342\346\352\356\362\334")/ge;
465 0         0 push( @board, $array[$_] );
466             }
467             }
468             else {
469 0         0 @board = configureboard( $type, $border, $corner, $legend );
470 0         0 for ( 0 .. 7 ) {
471 0         0 $array[$_] =~ s/(\d+)/'_' x $1/ge;
  0         0  
472 0         0 $array[$_] =~
473 0         0 s/([pnbrqkPNBRQK_])/mappiece(pos $array[$_],$_,$1,$FontMap{$type}{'OnBlack'},$FontMap{$type}
474             {'OnWhite'})/ge;
475 0         0 substr( $board[ $_ + 1 ], 1, 8 ) = $array[$_];
476             }
477             }
478 0         0 return @board;
479             }
480            
481             sub configureboard {
482 0     0 0 0 my $type = shift;
483 0         0 my $border = shift;
484 0         0 my $corner = shift;
485 0         0 my $legend = shift;
486 0         0 my $single = $border eq 'single';
487 0 0       0 my $box = $FontMap{$type}{ $single ? 'SingleBox' : 'DoubleBox' };
488 0         0 my @board;
489            
490 0 0       0 if ( $corner eq 'rounded' ) {
491 0 0       0 my $corners =
492             $FontMap{$type}{ $single ? 'SingleRounded' : 'DoubleRounded' };
493            
494 0         0 substr( $box, 0, 1 ) = substr( $corners, 0, 1 );
495 0         0 substr( $box, 2, 1 ) = substr( $corners, 1, 1 );
496 0         0 substr( $box, 5, 1 ) = substr( $corners, 2, 1 );
497 0         0 substr( $box, 7, 1 ) = substr( $corners, 3, 1 );
498             }
499 0         0 push( @board,
500             substr( $box, 0, 1 )
501             . substr( $box, 1, 1 ) x 8
502             . substr( $box, 2, 1 ) );
503 0         0 for ( 0 .. 7 ) {
504 0         0 push( @board, substr( $box, 3, 1 ) . ' ' x 8 . substr( $box, 4, 1 ) );
505             }
506 0         0 push( @board,
507             substr( $box, 5, 1 )
508             . substr( $box, 6, 1 ) x 8
509             . substr( $box, 7, 1 ) );
510 0 0       0 if ( $legend eq 'yes' ) {
511 0 0       0 my $left =
512             $FontMap{$type}{ $single ? 'SingleLeftLegend' : 'DoubleLeftLegend' };
513 0 0       0 my $bottom =
514             $FontMap{$type}{ $single
515             ? 'SingleBottomLegend'
516             : 'DoubleBottomLegend' };
517            
518 0         0 for ( 1 .. 8 ) {
519 0         0 substr( $board[$_], 0, 1 ) = substr( $left, $_ - 1, 1 );
520             }
521 0         0 substr( $board[-1], 1, 8 ) = $bottom;
522            
523             }
524 0         0 return @board;
525             }
526            
527             sub mappiece {
528 0     0 0 0 my $x = shift;
529 0         0 my $y = shift;
530 0         0 my $piece = shift;
531 0         0 my $ifonblack = shift;
532 0         0 my $ifonwhite = shift;
533 0         0 my $onwhite = $onwhite[ ( $y * 8 ) + $x ];
534 0         0 my $which = index( 'pnbrqkPNBRQK_', $piece );
535            
536 0 0       0 return substr( $onwhite ? $ifonwhite : $ifonblack, $which, 1 );
537             }
538            
539             sub epdgetboard {
540 0 0   0 1 0 if ( my $epd = shift ) {
541 0         0 epdset($epd);
542             }
543 0         0 return $w, $Kc, $Qc, $kc, $qc, %board;
544             }
545            
546             sub epdfromto {
547 0     0 1 0 my @moves = @_;
548 0         0 my @movelist;
549            
550 0         0 epdset();
551 0         0 for (@moves) {
552 0 0       0 if ($_) {
553 0         0 my ( $piece, $to, $from, $promotion ) = movetype( $w, $_ );
554 0         0 my $enpassant;
555 0         0 my $ep = '-';
556 0 0       0 my $castles = /O/ ? $_ : '';
557            
558 0 0       0 $Kc = 0 if $to eq 'h1';
559 0 0       0 $Qc = 0 if $to eq 'a1';
560 0 0       0 $kc = 0 if $to eq 'h8';
561 0 0       0 $qc = 0 if $to eq 'a8';
562            
563 0 0       0 if ( $piece eq "P" ) {
    0          
564 0 0       0 $piece = "p" if not $w;
565 0 0 0     0 $promotion = lc($promotion) if $promotion and not $w;
566 0 0       0 if ($from) {
567 0         0 $from .= substr( $to, 1, 1 );
568 0 0       0 if ($w) {
569 0         0 substr( $from, 1, 1 ) -= 1;
570             }
571             else {
572 0         0 $from++;
573             }
574             }
575             else {
576 0         0 $from = $to;
577            
578 0 0       0 if ($w) {
579 0         0 substr( $from, 1, 1 ) -= 1;
580 0 0       0 unless ($board{$from}) {
581 0         0 $ep = $from;
582 0         0 substr( $from, 1, 1 ) -= 1;
583             }
584             }
585             else {
586 0         0 $from++;
587 0 0       0 unless ($board{$from}) {
588 0         0 $ep = $from;
589 0         0 $from++;
590             }
591             }
592             }
593            
594 0 0       0 if ( substr( $from, 0, 1 ) ne substr( $to, 0, 1 ) ) {
595 0 0       0 if ( not $board{$to} ) {
596 0         0 $enpassant = $to;
597 0 0       0 if ($w) {
598 0         0 substr( $enpassant, 1, 1 ) =
599             chr( ord( substr( $enpassant, 1, 1 ) ) - 1 );
600             }
601             else {
602 0         0 substr( $enpassant, 1, 1 ) =
603             chr( ord( substr( $enpassant, 1, 1 ) ) + 1 );
604             }
605 0         0 $board{$enpassant} = undef;
606 0 0       0 $enpassant = defined($enpassant) ? $enpassant : '';
607 0 0       0 $from = defined($from) ? $from : '';
608 0 0       0 $to = defined($to) ? $to : '';
609             }
610             }
611 0 0       0 ( $board{$to}, $board{$from} ) =
612             ( $promotion ? $promotion : $board{$from}, undef );
613 0 0       0 $piece = defined($piece) ? $piece : '';
614 0 0       0 $from = defined($from) ? $from : '';
615 0 0       0 $to = defined($to) ? $to : '';
616 0 0       0 $promotion = defined($promotion) ? $promotion : '';
617             }
618             elsif ( $piece eq "KR" ) {
619 0         0 my ( $k_from, $r_from ) = unpack( "A2A2", $from );
620 0         0 my ( $k_to, $r_to ) = unpack( "A2A2", $to );
621            
622 0         0 ( $board{$k_to}, $board{$k_from} ) = ( $board{$k_from}, undef );
623 0         0 ( $board{$r_to}, $board{$r_from} ) = ( $board{$r_from}, undef );
624 0 0       0 if ($w) {
625 0         0 $Kc = $Qc = 0;
626             }
627             else {
628 0         0 $kc = $qc = 0;
629             }
630             }
631             else {
632 0         0 my @piece_at;
633             my @fromlist;
634            
635 0 0       0 $piece = lc($piece) if not $w;
636 0         0 @piece_at = psquares( $piece, %board );
637 0 0       0 if ($from) {
638 0         0 my @tmp;
639            
640 0 0       0 $from = defined($from) ? $from : '';
641 0 0       0 if ( $from =~ /[a-h]/ ) {
642 0         0 for (@piece_at) {
643 0 0       0 push( @tmp, $_ )
644             if ( substr( $_, 0, 1 ) eq $from );
645             }
646             }
647             else {
648            
649 0         0 for (@piece_at) {
650 0 0       0 push( @tmp, $_ )
651             if ( substr( $_, 1, 1 ) eq $from );
652             }
653             }
654 0         0 @piece_at = @tmp;
655             }
656            
657 0         0 for my $square (@piece_at) {
658 0         0 for ( @{ $move_table{ uc($piece) }{$square} } ) {
  0         0  
659 0 0       0 push( @fromlist, $square ) if $_ eq $to;
660             }
661             }
662 0 0       0 if ( scalar(@fromlist) != 1 ) {
663 0         0 for (@fromlist) {
664 0 0 0     0 if ( canmove( $piece, $to, $_, %board )
665             and isLegal( $w, $_, $to, %board ) )
666             {
667 0         0 $from = $_;
668 0         0 last;
669             }
670             }
671             }
672             else {
673 0         0 $from = $fromlist[0];
674             }
675 0 0       0 if ( $piece =~ /[RrKk]/ ) {
676 0 0       0 if ( $piece eq 'R' ) {
    0          
    0          
677 0 0       0 $Kc = 0 if $from eq 'h1';
678 0 0       0 $Qc = 0 if $from eq 'a1';
679             }
680             elsif ( $piece eq 'r' ) {
681 0 0       0 $kc = 0 if $from eq 'h8';
682 0 0       0 $qc = 0 if $from eq 'a8';
683             }
684             elsif ( $piece eq 'K' ) {
685 0         0 $Kc = $Qc = 0;
686             }
687             else {
688 0         0 $kc = $qc = 0;
689             }
690             }
691 0         0 ( $board{$to}, $board{$from} ) = ( $board{$from}, undef );
692 0 0       0 $piece = defined($piece) ? $piece : '';
693 0 0       0 $from = defined($from) ? $from : '';
694 0 0       0 $to = defined($to) ? $to : '';
695             }
696 0 0       0 my $movehash = {
    0          
    0          
    0          
    0          
    0          
697             piece => defined($piece) ? $piece : '',
698             from => defined($from) ? $from : '',
699             to => defined($to) ? $to : '',
700             promotion => defined($promotion) ? $promotion : '',
701             enpassant => defined($enpassant) ? $enpassant : '',
702             castles => defined($castles) ? $castles : '',
703             };
704 0         0 push(@movelist,$movehash);
705 0         0 $w ^= 1;
706             }
707             }
708 0         0 %board = ();
709 0         0 return @movelist;
710             }
711            
712             sub epdlist {
713 0     0 1 0 my @moves = @_;
714 0         0 my $debug = 0;
715 0         0 my @epdlist;
716 0         0 my $lineno = 1;
717            
718 0 0 0     0 if ( scalar @moves and $moves[-1] eq '1' ) {
719 0         0 $debug = 1;
720 0         0 pop @moves;
721 0 0       0 if (%board) {
722 0         0 print "\%board initialized\n";
723             }
724             else {
725 0         0 print "\%board uninitialized\n";
726             }
727             }
728 0         0 epdset();
729 0         0 for (@moves) {
730 0 0       0 Print(%board) if $debug;
731 0 0       0 if ($_) {
732 0         0 my ( $piece, $to, $from, $promotion ) = movetype( $w, $_ );
733 0         0 my $enpassant;
734 0         0 my $ep = '-';
735            
736 0 0       0 $Kc = 0 if $to eq 'h1';
737 0 0       0 $Qc = 0 if $to eq 'a1';
738 0 0       0 $kc = 0 if $to eq 'h8';
739 0 0       0 $qc = 0 if $to eq 'a8';
740            
741 0 0       0 if ($debug) {
742 0         0 print "Move[$lineno]='$_'";
743 0         0 $lineno++;
744 0 0       0 if ($piece) {
745 0         0 print ", piece='$piece'";
746 0 0       0 print ", to='$to'" if $to;
747 0 0       0 print ", from='$from'" if $from;
748 0 0       0 print ", promotion='$promotion'" if $promotion;
749             }
750 0         0 print "\n";
751             }
752            
753 0 0       0 if ( $piece eq "P" ) {
    0          
754 0 0       0 $piece = "p" if not $w;
755 0 0 0     0 $promotion = lc($promotion) if $promotion and not $w;
756 0 0       0 if ($from) {
757 0         0 $from .= substr( $to, 1, 1 );
758 0 0       0 if ($w) {
759 0         0 substr( $from, 1, 1 ) -= 1;
760             }
761             else {
762            
763 0         0 $from++;
764             }
765             }
766             else {
767 0         0 $from = $to;
768            
769 0 0       0 if ($w) {
770 0         0 substr( $from, 1, 1 ) -= 1;
771 0 0       0 unless ($board{$from}) {
772 0         0 $ep = $from;
773 0         0 substr( $from, 1, 1 ) -= 1;
774             }
775             }
776             else {
777 0         0 $from++;
778 0 0       0 unless ($board{$from}) {
779 0         0 $ep = $from;
780 0         0 $from++;
781             }
782             }
783             }
784            
785 0 0       0 if ( substr( $from, 0, 1 ) ne substr( $to, 0, 1 ) ) {
786 0 0       0 if ( not $board{$to} ) {
787 0         0 $enpassant = $to;
788 0 0       0 if ($w) {
789 0         0 substr( $enpassant, 1, 1 ) =
790             chr( ord( substr( $enpassant, 1, 1 ) ) - 1 );
791             }
792             else {
793 0         0 substr( $enpassant, 1, 1 ) =
794             chr( ord( substr( $enpassant, 1, 1 ) ) + 1 );
795             }
796 0         0 $board{$enpassant} = undef;
797 0 0       0 if ($debug) {
798 0 0       0 print "\$enpassant='$enpassant' " if $enpassant;
799 0 0       0 print "\$from='$from' " if $from;
800 0 0       0 print "\$to='$to'" if $to;
801 0         0 print "\n";
802             }
803             }
804             }
805 0 0       0 ( $board{$to}, $board{$from} ) =
806             ( $promotion ? $promotion : $board{$from}, undef );
807 0 0       0 if ($debug) {
808 0 0       0 print "\$piece='$piece' " if $piece;
809 0 0       0 print "\$from='$from' " if $from;
810 0 0       0 print "\$to='$to' " if $to;
811 0 0       0 print "\$promotion='$promotion' " if $promotion;
812             }
813 0         0 push( @epdlist, epd( $w, $Kc, $Qc, $kc, $qc, $ep, %board ) );
814 0 0       0 if ($debug) {
815 0         0 print "$epdlist[-1]\n";
816             }
817             }
818             elsif ( $piece eq "KR" ) {
819 0         0 my ( $k_from, $r_from ) = unpack( "A2A2", $from );
820 0         0 my ( $k_to, $r_to ) = unpack( "A2A2", $to );
821            
822 0         0 ( $board{$k_to}, $board{$k_from} ) = ( $board{$k_from}, undef );
823 0         0 ( $board{$r_to}, $board{$r_from} ) = ( $board{$r_from}, undef );
824 0 0       0 if ($w) {
825 0         0 $Kc = $Qc = 0;
826             }
827             else {
828 0         0 $kc = $qc = 0;
829             }
830 0 0       0 if ($debug) {
831 0 0       0 print $w ? "White" : "Black",
832             " castles from $k_from to $k_to\n";
833             }
834 0         0 push( @epdlist, epd( $w, $Kc, $Qc, $kc, $qc, $ep, %board ) );
835 0 0       0 if ($debug) {
836 0         0 print "$epdlist[-1]\n";
837             }
838             }
839             else {
840 0         0 my @piece_at;
841             my @fromlist;
842            
843 0 0       0 $piece = lc($piece) if not $w;
844 0         0 @piece_at = psquares( $piece, %board );
845 0 0       0 if ($debug) {
846 0 0       0 print "\@piece_at=", join( ",", @piece_at ), "\n"
847             if @piece_at;
848             }
849 0 0       0 if ($from) {
850 0         0 my @tmp;
851            
852 0 0       0 if ($debug) {
853 0 0       0 print "\$from='$from'\n" if $from;
854             }
855 0 0       0 if ( $from =~ /[a-h]/ ) {
856 0         0 for (@piece_at) {
857 0 0       0 push( @tmp, $_ )
858             if ( substr( $_, 0, 1 ) eq $from );
859             }
860             }
861             else {
862            
863 0         0 for (@piece_at) {
864 0 0       0 push( @tmp, $_ )
865             if ( substr( $_, 1, 1 ) eq $from );
866             }
867             }
868 0         0 @piece_at = @tmp;
869             }
870            
871 0         0 for my $square (@piece_at) {
872 0         0 for ( @{ $move_table{ uc($piece) }{$square} } ) {
  0         0  
873 0 0       0 push( @fromlist, $square ) if $_ eq $to;
874             }
875             }
876 0 0       0 print "scalar \@fromlist = ", scalar(@fromlist), "\n" if $debug;
877 0 0       0 if ( scalar(@fromlist) != 1 ) {
878 0 0       0 if ($debug) {
879 0 0       0 print "\@fromlist=", join( ",", @fromlist ), "\n"
880             if @fromlist;
881             }
882 0         0 for (@fromlist) {
883 0 0 0     0 if ( canmove( $piece, $to, $_, %board )
884             and isLegal( $w, $_, $to, %board ) )
885             {
886 0         0 $from = $_;
887 0         0 last;
888             }
889             }
890             }
891             else {
892 0         0 $from = $fromlist[0];
893             }
894 0 0       0 if ( $piece =~ /[RrKk]/ ) {
895 0 0       0 if ( $piece eq 'R' ) {
    0          
    0          
896 0 0       0 $Kc = 0 if $from eq 'h1';
897 0 0       0 $Qc = 0 if $from eq 'a1';
898             }
899             elsif ( $piece eq 'r' ) {
900 0 0       0 $kc = 0 if $from eq 'h8';
901 0 0       0 $qc = 0 if $from eq 'a8';
902             }
903             elsif ( $piece eq 'K' ) {
904 0         0 $Kc = $Qc = 0;
905             }
906             else {
907 0         0 $kc = $qc = 0;
908             }
909             }
910 0         0 ( $board{$to}, $board{$from} ) = ( $board{$from}, undef );
911 0 0       0 if ($debug) {
912 0 0       0 print "\@piece_at=", join( ",", @piece_at ), "\n"
913             if @piece_at;
914 0 0       0 print "\$piece='$piece' " if $piece;
915 0 0       0 print "\$from='$from' " if $from;
916 0 0       0 print "\$to='$to' " if $to;
917             }
918 0         0 push( @epdlist, epd( $w, $Kc, $Qc, $kc, $qc, $ep, %board ) );
919 0 0       0 if ($debug) {
920 0         0 print "$epdlist[-1]\n";
921             }
922 0 0       0 if ( not $from ) {
923 0         0 ShowPieces(%board);
924 0         0 Print(%board);
925             try {
926 0     0   0 $from;
927             } catch {
928 0     0   0 print "From undefined\n";
929 0         0 exit;
930 0         0 };
931             }
932             }
933 0         0 $w ^= 1;
934             }
935             }
936 0         0 %board = ();
937 0         0 return @epdlist;
938             }
939            
940             sub isLegal {
941 0     0 0 0 my ( $w, $from, $to, %board ) = @_;
942 0         0 my %board_copy = %board;
943 0         0 my $kings_square;
944             my @attack_list;
945            
946 0         0 ( $board_copy{$to}, $board_copy{$from} ) = ( $board_copy{$from}, undef );
947 0 0       0 my $findking = $w ? 'K' : 'k';
948 0         0 for ( keys %board_copy ) {
949 0 0 0     0 if ( $board_copy{$_} and ( $board_copy{$_} eq $findking ) ) {
950 0         0 $kings_square = $_;
951 0         0 last;
952             }
953             }
954 0 0       0 my $mask = $w ? 'qrnbp' : 'QRNBP';
955 0         0 for my $square ( keys %board_copy ) {
956 0 0 0     0 if ( $board_copy{$square} and $mask =~ /$board_copy{$square}/ ) {
957 0         0 for ( @{ $move_table{ uc( $board_copy{$square} ) }{$square} } ) {
  0         0  
958 0 0       0 push( @attack_list, $square ) if $_ eq $kings_square;
959             }
960             }
961             }
962 0         0 for (@attack_list) {
963 0 0       0 if ( canmove( $board_copy{$_}, $kings_square, $_, %board_copy ) ) {
964 0         0 return 0;
965             }
966             }
967 0         0 return 1;
968             }
969            
970             sub ShowPieces {
971 0     0 0 0 my %board = @_;
972            
973 0         0 for my $square ( keys %board ) {
974 0         0 my $piece = $board{$square};
975 0 0       0 next unless $piece;
976 0         0 print "'$square' == ", $piece, "\n";
977             }
978 0         0 return;
979             }
980            
981             sub Print {
982 0     0 0 0 my (%board) = @_;
983 0         0 my $whitesquare = 1;
984 0         0 my @rows = (
985             [qw(a8 b8 c8 d8 e8 f8 g8 h8)], [qw(a7 b7 c7 d7 e7 f7 g7 h7)],
986             [qw(a6 b6 c6 d6 e6 f6 g6 h6)], [qw(a5 b5 c5 d5 e5 f5 g5 h5)],
987             [qw(a4 b4 c4 d4 e4 f4 g4 h4)], [qw(a3 b3 c3 d3 e3 f3 g3 h3)],
988             [qw(a2 b2 c2 d2 e2 f2 g2 h2)], [qw(a1 b1 c1 d1 e1 f1 g1 h1)]
989             );
990            
991 0         0 for ( 0 .. 7 ) {
992 0         0 print "\n", 8 - $_, " ";
993 0         0 for ( @{ $rows[$_] } ) {
  0         0  
994 0 0       0 if ( $board{$_} ) {
    0          
995 0         0 print $board{$_};
996             }
997             elsif ($whitesquare) {
998 0         0 print ' ';
999             }
1000             else {
1001 0         0 print '-';
1002             }
1003 0         0 $whitesquare ^= 1;
1004             }
1005 0         0 $whitesquare ^= 1;
1006             }
1007 0         0 print "\n abcdefgh\n\n";
1008 0         0 return;
1009             }
1010            
1011             sub movetype {
1012 0     0 0 0 my ( $w, $move ) = @_;
1013 0         0 my @result = "'$move':Not yet handled";
1014 0         0 my $from;
1015             my $to;
1016            
1017 0 0       0 if ( $move =~ /^O-O(?:\+|\#)?$/ ) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1018 0 0       0 if ($w) {
1019 0         0 $from = "e1h1";
1020 0         0 $to = "g1f1";
1021             }
1022             else {
1023 0         0 $from = "e8h8";
1024 0         0 $to = "g8f8";
1025             }
1026 0         0 @result = ( "KR", $to, $from );
1027             }
1028             elsif ( $move =~ /^O-O-O(?:\+|\#)?$/ ) {
1029            
1030 0 0       0 if ($w) {
1031 0         0 $from = "e1a1";
1032 0         0 $to = "c1d1";
1033             }
1034             else {
1035 0         0 $from = "e8a8";
1036 0         0 $to = "c8d8";
1037             }
1038 0         0 @result = ( "KR", $to, $from );
1039             }
1040             elsif ( $move =~ /^([2-7])([a-h][1-8])(?:\+|\#)?$/ ) {
1041 0         0 @result = ( "P", $2 );
1042             }
1043             elsif ( $move =~ /^([a-h][1-8])(?:\+|\#)?$/ ) {
1044 0         0 @result = ( "P", $1 );
1045             }
1046             elsif ( $move =~ /^([a-h])x?([a-h][1-8])(?:\+|\#)?$/ ) {
1047 0         0 @result = ( "P", $2, $1 );
1048             }
1049             elsif ( $move =~ /^([a-h][18])=?([RNBQ])(?:\+|\#)?$/ ) {
1050 0         0 @result = ( "P", $1, undef, $2 );
1051             }
1052             elsif ( $move =~ /^([a-h])x([a-h][18])=?([RNBQ])(?:\+|\#)?$/ ) {
1053 0         0 @result = ( "P", $2, $1, $3 );
1054             }
1055             elsif ( $move =~ /^([RNBQK])([a-h][1-8])(?:\+|\#)?$/ ) {
1056 0         0 @result = ( $1, $2 );
1057             }
1058             elsif ( $move =~ /^([RNBQK])x([a-h][1-8])(?:\+|\#)?$/ ) {
1059 0         0 @result = ( $1, $2 );
1060             }
1061             elsif ( $move =~ /^([RNBQK])([a-h]|[1-8])([a-h][1-8])(?:\+|\#)?$/ ) {
1062 0         0 @result = ( $1, $3, $2 );
1063             }
1064             elsif ( $move =~ /^([RNBQK])([a-h][1-8])([a-h][1-8])(?:\+|\#)?$/ ) {
1065 0         0 @result = ( $1, $3, $2 );
1066             }
1067             elsif ( $move =~ /^([RNBQK])([a-h]|[1-8])x([a-h][1-8])(?:\+|\#)?$/ ) {
1068 0         0 @result = ( $1, $3, $2 );
1069             }
1070             elsif ( $move =~ /^([RNBQK])([a-h][1-8])x([a-h][1-8])(?:\+|\#)?$/ ) {
1071 0         0 @result = ( $1, $3, $2 );
1072             }
1073 0         0 return @result;
1074             }
1075            
1076             sub psquares {
1077 0     0 1 0 my ( $piece, %board ) = @_;
1078            
1079 0 0 0     0 return grep { $_ and $board{$_} and ( $board{$_} eq $piece ) } sort keys %board;
  0         0  
1080             }
1081            
1082             sub epd {
1083 0     0 1 0 my ( $w, $Kc, $Qc, $kc, $qc, $ep, %board ) = @_;
1084 0         0 my @key = qw(
1085             a8 b8 c8 d8 e8 f8 g8 h8
1086             a7 b7 c7 d7 e7 f7 g7 h7
1087             a6 b6 c6 d6 e6 f6 g6 h6
1088             a5 b5 c5 d5 e5 f5 g5 h5
1089             a4 b4 c4 d4 e4 f4 g4 h4
1090             a3 b3 c3 d3 e3 f3 g3 h3
1091             a2 b2 c2 d2 e2 f2 g2 h2
1092             a1 b1 c1 d1 e1 f1 g1 h1
1093             );
1094 0         0 my $n;
1095             my $piece;
1096 0         0 my $epd;
1097            
1098 0         0 for ( 0 .. 63 ) {
1099 0 0 0     0 if ( $_ and ( $_ % 8 ) == 0 ) {
1100 0 0       0 if ($n) {
1101 0         0 $epd .= "$n";
1102 0         0 $n = 0;
1103             }
1104 0         0 $epd .= "/";
1105             }
1106 0         0 $piece = $board{ $key[$_] };
1107            
1108 0 0       0 if ($piece) {
1109 0 0       0 if ($n) {
1110 0         0 $epd .= "$n";
1111 0         0 $n = 0;
1112             }
1113 0         0 $epd .= $piece;
1114             }
1115             else {
1116 0         0 $n++;
1117             }
1118             }
1119            
1120 0 0       0 $epd .= "$n" if $n;
1121 0 0       0 $epd .= ( $w ? " b" : " w" );
1122            
1123 0 0 0     0 if ( $Kc or $Qc or $kc or $qc ) {
      0        
      0        
1124 0         0 $epd .= " ";
1125 0 0       0 $epd .= "K" if $Kc;
1126 0 0       0 $epd .= "Q" if $Qc;
1127 0 0       0 $epd .= "k" if $kc;
1128 0 0       0 $epd .= "q" if $qc;
1129             }
1130             else {
1131 0         0 $epd .= " -";
1132             }
1133 0         0 $epd .= " $ep";
1134 0         0 return $epd;
1135             }
1136            
1137             sub canmove {
1138 0     0 0 0 my ( $piece, $to, $from, %board ) = @_;
1139 0         0 my $lto;
1140             my $rto;
1141 0         0 my $lfrom;
1142 0         0 my $rfrom;
1143 0         0 my $result = 1;
1144 0         0 my $offset = 1;
1145 0         0 my $roffset = 1;
1146 0         0 my $loffset = 1;
1147 0         0 my $c = 0;
1148            
1149 0         0 $to =~ /(.)(.)/;
1150 0         0 ( $lto, $rto ) = ( $1, $2 );
1151 0         0 $from =~ /(.)(.)/;
1152 0         0 ( $lfrom, $rfrom ) = ( $1, $2 );
1153            
1154 0 0 0     0 if ( $board{$from} and $board{to} ) {
    0 0        
    0          
1155 0 0 0     0 if ( defined( $board{$from} ) and defined( $board{$to} ) ) {
1156 0 0       0 if ( $board{$from}->color() == $board{$to}->color() ) {
1157 0         0 $result = 0;
1158             }
1159             }
1160             }
1161             elsif ( ( $rto eq $rfrom ) or ( $lto eq $lfrom ) ) {
1162            
1163 0 0 0     0 if ( ( $rto eq $rfrom and $lto lt $lfrom )
      0        
      0        
1164             or ( $lto eq $lfrom and $rto lt $rfrom ) )
1165             {
1166 0         0 $offset = -1;
1167             }
1168            
1169 0 0       0 if ( $lto eq $lfrom ) {
1170 0         0 $c = 1;
1171             }
1172 0         0 while ( $from ne $to ) {
1173 0         0 substr( $from, $c, 1 ) =
1174             chr( ord( substr( $from, $c, 1 ) ) + $offset );
1175 0 0       0 if ( defined( $board{$from} ) ) {
1176 0 0       0 $result = 0 if ( $from ne $to );
1177 0         0 last;
1178             }
1179             }
1180             }
1181             elsif ( $piece =~ /[bq]/i ) {
1182            
1183 0 0       0 if ( $rto lt $rfrom ) {
1184 0         0 $roffset = -1;
1185             }
1186 0 0       0 if ( $lto lt $lfrom ) {
1187 0         0 $loffset = -1;
1188             }
1189 0         0 while ( $from ne $to ) {
1190 0         0 substr( $from, 0, 1 ) =
1191             chr( ord( substr( $from, 0, 1 ) ) + $loffset );
1192 0         0 substr( $from, 1, 1 ) =
1193             chr( ord( substr( $from, 1, 1 ) ) + $roffset );
1194 0 0       0 if ( defined( $board{$from} ) ) {
1195 0 0       0 $result = 0 if ( $from ne $to );
1196 0         0 last;
1197             }
1198             }
1199             }
1200 0         0 return $result;
1201             }
1202            
1203             sub epdTaxonomy {
1204 0     0 1 0 my (%options) = @_;
1205 0         0 my @moves = @{$options{'moves'}};
  0         0  
1206 0         0 my @results;
1207 0         0 my ($eco,$nic,$opening);
1208 0         0 my @epd = reverse (epdlist(@moves));
1209            
1210 0 0       0 if ($options{'all'}) {
1211 0         0 $eco = epdcode('ECO',\@epd);
1212 0         0 $nic = epdcode('NIC',\@epd);
1213 0         0 $opening = epdcode('Opening',\@epd);
1214             }
1215             else {
1216 0         0 for (lc (keys %options)) {
1217 0 0       0 if ($_ eq 'eco') {
    0          
    0          
1218 0         0 $eco = epdcode('ECO',\@epd);
1219             }
1220             elsif ($_ eq 'nic') {
1221 0         0 $nic = epdcode('NIC',\@epd);
1222             }
1223             elsif ($_ eq 'Opening') {
1224 0         0 $opening = epdcode('Opening',\@epd);
1225             }
1226             }
1227             }
1228 0 0       0 if ($options{'astags'}) {
1229 0 0       0 push(@results,"[ECO \"$eco\"]") if $eco;
1230 0 0       0 push(@results,"[NIC \"$nic\"]") if $nic;
1231 0 0       0 push(@results,"[Opening \"$opening\"]") if $opening;
1232             }
1233             else {
1234 0 0       0 push(@results,$eco) if $eco;
1235 0 0       0 push(@results,$nic) if $nic;
1236 0 0       0 push(@results,$opening) if $opening;
1237             }
1238 0         0 return @results;
1239             }
1240            
1241             sub GetPaths {
1242 10     10 0 40 my $module = shift;
1243 10         21 my $sep;
1244             my $dbECO;
1245 0         0 my $dbNIC;
1246 0         0 my $dbOpening;
1247            
1248 10         188 s/::/\//g, s/$/.pm/ for $module;
1249 10         41 for (@INC) {
1250 110 50       351 if (/(\\|\/)Perl[\\\/]site[\\\/]lib$/i) {
1251 0         0 $sep = $1;
1252 0         0 $module = $_ . $sep . $module;
1253 0         0 last;
1254             }
1255             }
1256 10         179 $module =~ s/EPD.pm//;
1257 10         9887 $dbECO = $module . 'db' . $sep . 'ECO.stor';
1258 10         22200 $dbNIC = $module . 'db' . $sep . 'NIC.stor';
1259 10         7055 $dbOpening = $module . 'db' . $sep . 'Opening.stor';
1260 10         5626 return ($dbECO,$dbNIC,$dbOpening);
1261             }
1262            
1263             1;
1264             __END__