| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | #!/usr/bin/perl -w | 
| 2 |  |  |  |  |  |  | ####----------------------------------- | 
| 3 |  |  |  |  |  |  | ### File	: Trad.pm | 
| 4 |  |  |  |  |  |  | ### Author	: C.Minc | 
| 5 |  |  |  |  |  |  | ### Purpose	: chess translator | 
| 6 |  |  |  |  |  |  | ### Version	: 1.1 2007/12/22 | 
| 7 |  |  |  |  |  |  | ### copyright GNU license | 
| 8 |  |  |  |  |  |  | ####----------------------------------- | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | package Trad ; | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | #package Chess::ChessKit::Trad ; | 
| 14 |  |  |  |  |  |  |  | 
| 15 | 1 |  |  | 1 |  | 1686 | use warnings; | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 40 |  | 
| 16 | 1 |  |  | 1 |  | 7 | use strict; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 68 |  | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | =head1 NAME | 
| 19 |  |  |  |  |  |  |  | 
| 20 |  |  |  |  |  |  | ChessKit::Trad | 
| 21 |  |  |  |  |  |  |  | 
| 22 |  |  |  |  |  |  | =head1 VERSION | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | Version 1.1 | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | =cut | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | see ChessKit | 
| 31 |  |  |  |  |  |  |  | 
| 32 |  |  |  |  |  |  | =head1 FUNCTIONS | 
| 33 |  |  |  |  |  |  |  | 
| 34 |  |  |  |  |  |  | =head2 sub dscrip | 
| 35 |  |  |  |  |  |  |  | 
| 36 |  |  |  |  |  |  | see ChessKit | 
| 37 |  |  |  |  |  |  |  | 
| 38 |  |  |  |  |  |  | =head2 sub mauv | 
| 39 |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  | retrieve the move from notation | 
| 41 |  |  |  |  |  |  | see ChessKit | 
| 42 |  |  |  |  |  |  |  | 
| 43 |  |  |  |  |  |  | =head2 sub promote | 
| 44 |  |  |  |  |  |  |  | 
| 45 |  |  |  |  |  |  | retrieve the element of pawn promotion | 
| 46 |  |  |  |  |  |  | see ChessKit | 
| 47 |  |  |  |  |  |  |  | 
| 48 |  |  |  |  |  |  | =head2 sub resolve | 
| 49 |  |  |  |  |  |  |  | 
| 50 |  |  |  |  |  |  | resolve move ambiguity of the destination square | 
| 51 |  |  |  |  |  |  | see ChessKit | 
| 52 |  |  |  |  |  |  |  | 
| 53 |  |  |  |  |  |  | =head2 sub resolve_deb | 
| 54 |  |  |  |  |  |  |  | 
| 55 |  |  |  |  |  |  | resolve move ambiguity of the starting square | 
| 56 |  |  |  |  |  |  | see ChessKit | 
| 57 |  |  |  |  |  |  |  | 
| 58 |  |  |  |  |  |  | =head2 sub trad | 
| 59 |  |  |  |  |  |  |  | 
| 60 |  |  |  |  |  |  | High level interface for translating notation | 
| 61 |  |  |  |  |  |  | from languages | 
| 62 |  |  |  |  |  |  | see ChessKit | 
| 63 |  |  |  |  |  |  |  | 
| 64 |  |  |  |  |  |  | =cut | 
| 65 |  |  |  |  |  |  |  | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  |  | 
| 68 |  |  |  |  |  |  | =head1 AUTHOR | 
| 69 |  |  |  |  |  |  |  | 
| 70 |  |  |  |  |  |  | Charles Minc, C<<  >> | 
| 71 |  |  |  |  |  |  |  | 
| 72 |  |  |  |  |  |  | =head1 BUGS | 
| 73 |  |  |  |  |  |  |  | 
| 74 |  |  |  |  |  |  | Please report any bugs or feature requests to | 
| 75 |  |  |  |  |  |  | C, or through the web interface at | 
| 76 |  |  |  |  |  |  | L. | 
| 77 |  |  |  |  |  |  | I will be notified, and then you'll automatically be notified of progress on | 
| 78 |  |  |  |  |  |  | your bug as I make changes. | 
| 79 |  |  |  |  |  |  |  | 
| 80 |  |  |  |  |  |  | =head1 ACKNOWLEDGEMENTS | 
| 81 |  |  |  |  |  |  |  | 
| 82 |  |  |  |  |  |  | =head1 COPYRIGHT & LICENSE | 
| 83 |  |  |  |  |  |  |  | 
| 84 |  |  |  |  |  |  | Copyright 2005 Charles Minc, all rights reserved. | 
| 85 |  |  |  |  |  |  |  | 
| 86 |  |  |  |  |  |  | This program is free software; you can redistribute it and/or modify it | 
| 87 |  |  |  |  |  |  | under the same terms as Perl itself. | 
| 88 |  |  |  |  |  |  |  | 
| 89 |  |  |  |  |  |  | =cut | 
| 90 |  |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  | our $VERSION = '1.0' ; | 
| 92 |  |  |  |  |  |  |  | 
| 93 | 1 |  |  | 1 |  | 5 | use strict ; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 25 |  | 
| 94 | 1 |  |  | 1 |  | 1205 | use Symbol ; | 
|  | 1 |  |  |  |  | 1085 |  | 
|  | 1 |  |  |  |  | 107 |  | 
| 95 | 1 |  |  | 1 |  | 8 | use Chess::ChessKit::Board  ; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 34 |  | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  |  | 
| 98 |  |  |  |  |  |  | require Exporter ; | 
| 99 |  |  |  |  |  |  |  | 
| 100 | 1 |  |  |  |  | 3687 | use vars qw( | 
| 101 |  |  |  |  |  |  | @ISA | 
| 102 |  |  |  |  |  |  | @EXPORT | 
| 103 | 1 |  |  | 1 |  | 7 | ); | 
|  | 1 |  |  |  |  | 1 |  | 
| 104 |  |  |  |  |  |  | our @ISA =qw(Exporter) ; | 
| 105 |  |  |  |  |  |  |  | 
| 106 |  |  |  |  |  |  | our @EXPORT = qw( %country $bd ); | 
| 107 |  |  |  |  |  |  |  | 
| 108 |  |  |  |  |  |  | # this part concerns only algrbraic notation | 
| 109 |  |  |  |  |  |  |  | 
| 110 |  |  |  |  |  |  | our %country=( | 
| 111 |  |  |  |  |  |  | Czech       =>'Czech     ', | 
| 112 |  |  |  |  |  |  | Danish      =>'Danish    ', | 
| 113 |  |  |  |  |  |  | Dutch       =>'Dutch     ', | 
| 114 |  |  |  |  |  |  | English     =>'English   ', | 
| 115 |  |  |  |  |  |  | Estonian    =>'Estonian  ', | 
| 116 |  |  |  |  |  |  | Finnish     =>'Finnish   ', | 
| 117 |  |  |  |  |  |  | French      =>'French    ', | 
| 118 |  |  |  |  |  |  | German      =>'German    ', | 
| 119 |  |  |  |  |  |  | Hungarian   =>'Hungarian ', | 
| 120 |  |  |  |  |  |  | Icelandic   =>'Icelandic ', | 
| 121 |  |  |  |  |  |  | Italian     =>'Italian   ', | 
| 122 |  |  |  |  |  |  | Norwegian   =>'Norwegian ', | 
| 123 |  |  |  |  |  |  | Polish      =>'Polish    ', | 
| 124 |  |  |  |  |  |  | Portuguese  =>'Portuguese', | 
| 125 |  |  |  |  |  |  | Romanian    =>'Romanian  ', | 
| 126 |  |  |  |  |  |  | Spanish     =>'Spanish   ', | 
| 127 |  |  |  |  |  |  | Swedish     =>'Swedish   ') ; | 
| 128 |  |  |  |  |  |  |  | 
| 129 |  |  |  |  |  |  |  | 
| 130 |  |  |  |  |  |  | sub trad { | 
| 131 | 0 |  |  | 0 |  |  | (my $fileresult, my $file, my $lang ,my $lang2)=@_ ; | 
| 132 |  |  |  |  |  |  |  | 
| 133 | 0 |  |  |  |  |  | my %trad2eng=( | 
| 134 |  |  |  |  |  |  | Czech       =>'JSVDK', | 
| 135 |  |  |  |  |  |  | Danish      =>'SLTDK', | 
| 136 |  |  |  |  |  |  | Dutch       =>'PLTDK', | 
| 137 |  |  |  |  |  |  | English     =>'NBRQK', | 
| 138 |  |  |  |  |  |  | Estonian    =>'ROVLK', | 
| 139 |  |  |  |  |  |  | Finnish     =>'RLTDK', | 
| 140 |  |  |  |  |  |  | French      =>'CFTDR', | 
| 141 |  |  |  |  |  |  | German      =>'SLTDK', | 
| 142 |  |  |  |  |  |  | Hungarian   =>'HFBVK', | 
| 143 |  |  |  |  |  |  | Icelandic   =>'RBHDK', | 
| 144 |  |  |  |  |  |  | Italian     =>'CATDR', | 
| 145 |  |  |  |  |  |  | Norwegian   =>'SLTDK', | 
| 146 |  |  |  |  |  |  | Polish      =>'SGWHK', | 
| 147 |  |  |  |  |  |  | Portuguese  =>'CBTDR', | 
| 148 |  |  |  |  |  |  | Romanian    =>'CNTDR', | 
| 149 |  |  |  |  |  |  | Spanish     =>'CATDR', | 
| 150 |  |  |  |  |  |  | Swedish     =>'SLTDK') ; | 
| 151 |  |  |  |  |  |  |  | 
| 152 | 0 |  |  |  |  |  | print "from $lang to $lang2\n " ; | 
| 153 | 0 |  |  |  |  |  | my $piece=$trad2eng{$lang} ; | 
| 154 | 0 |  |  |  |  |  | my $prom=substr($piece,0,4) ; | 
| 155 | 0 |  |  |  |  |  | my @ltr=split( // ,$piece ); | 
| 156 | 0 |  |  |  |  |  | my @ltr2=split( // ,$trad2eng{$lang2} ); | 
| 157 |  |  |  |  |  |  |  | 
| 158 | 0 |  |  |  |  |  | my %trad2en=("" => "", $ltr[0] => $ltr2[0],  $ltr[1] => $ltr2[1],  $ltr[2] => $ltr2[2],  $ltr[3] => $ltr2[3], $ltr[4] => $ltr2[4]) ; | 
| 159 |  |  |  |  |  |  |  | 
| 160 | 0 |  |  |  |  |  | open(OFILE,">",$fileresult) ; | 
| 161 |  |  |  |  |  |  |  | 
| 162 | 0 | 0 |  |  |  |  | open(HFILE,$file) or die "cannot open file $file  "; | 
| 163 | 0 |  |  |  |  |  | my @line= ; | 
| 164 |  |  |  |  |  |  |  | 
| 165 | 0 |  |  |  |  |  | foreach (@line) { | 
| 166 |  |  |  |  |  |  |  | 
| 167 |  |  |  |  |  |  | # because we can find also something like that :3. d4, cxd4 ; 4. Cxd4, e5; 5. Cdb5, Cf6 ; | 
| 168 | 0 |  |  |  |  |  | s/([$piece]?)([a-h]?[1-8]?\s*x?\s*[a-h][1-8][\+#]?\s*)(?:[,;]*)(\s*\=?\s*)([$prom]?)/$trad2en{$1}$2$3$trad2en{$4}/g ; | 
| 169 |  |  |  |  |  |  |  | 
| 170 |  |  |  |  |  |  | # piece  ^^ | 
| 171 |  |  |  |  |  |  | # column or line ^^^  ^^^ | 
| 172 |  |  |  |  |  |  | # capture                     ^ | 
| 173 |  |  |  |  |  |  | #  destination square               ^^^  ^^^ | 
| 174 |  |  |  |  |  |  | #  promotion                                                                 ^^^ | 
| 175 |  |  |  |  |  |  | # | 
| 176 |  |  |  |  |  |  |  | 
| 177 |  |  |  |  |  |  | # just as above to delete semi-colons and commas | 
| 178 | 0 |  |  |  |  |  | s/([O-]?O-O\s*)(?:[,;]*)/$1/g ; | 
| 179 |  |  |  |  |  |  |  | 
| 180 | 0 |  |  |  |  |  | print OFILE $_ ; | 
| 181 |  |  |  |  |  |  | } | 
| 182 |  |  |  |  |  |  |  | 
| 183 | 0 |  |  |  |  |  | close(HFILE) ; | 
| 184 | 0 |  |  |  |  |  | close(OFILE) ; | 
| 185 | 0 |  |  |  |  |  | return ; | 
| 186 |  |  |  |  |  |  | } | 
| 187 |  |  |  |  |  |  |  | 
| 188 |  |  |  |  |  |  |  | 
| 189 |  |  |  |  |  |  | # the following part concerns only english descriptive notation | 
| 190 |  |  |  |  |  |  |  | 
| 191 |  |  |  |  |  |  | my @from , | 
| 192 |  |  |  |  |  |  | my @to ; | 
| 193 |  |  |  |  |  |  | my $status={} ;			# used to valid castling | 
| 194 |  |  |  |  |  |  | my @moves ; | 
| 195 |  |  |  |  |  |  | our $bd ; | 
| 196 |  |  |  |  |  |  |  | 
| 197 |  |  |  |  |  |  |  | 
| 198 |  |  |  |  |  |  | # this array below is used to reverse the column numbering of the Black moves | 
| 199 |  |  |  |  |  |  | my @black=(0,8,7,6,5,4,3,2,1) ; | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | # the following make the correspondance of the row naming between | 
| 202 |  |  |  |  |  |  | # descriptive and algebraic notation | 
| 203 |  |  |  |  |  |  |  | 
| 204 |  |  |  |  |  |  | my %algebra=(QR=>'a', | 
| 205 |  |  |  |  |  |  | QN=>'b', | 
| 206 |  |  |  |  |  |  | QB=>'c', | 
| 207 |  |  |  |  |  |  | Q=> 'd', | 
| 208 |  |  |  |  |  |  | K=> 'e', | 
| 209 |  |  |  |  |  |  | KB=>'f', | 
| 210 |  |  |  |  |  |  | KN=>'g', | 
| 211 |  |  |  |  |  |  | KR=>'h') ; | 
| 212 |  |  |  |  |  |  |  | 
| 213 |  |  |  |  |  |  | sub dscrip { | 
| 214 |  |  |  |  |  |  |  | 
| 215 | 0 |  |  | 0 |  |  | my (%arg)=@_ ; | 
| 216 | 0 |  |  |  |  |  | my @sauces=@{$arg{mov}} ; | 
|  | 0 |  |  |  |  |  |  | 
| 217 | 0 | 0 |  |  |  |  | my %study=%{$arg{ini}}if ( defined($arg{ini})) ; | 
|  | 0 |  |  |  |  |  |  | 
| 218 | 0 |  |  |  |  |  | @moves=() ; | 
| 219 |  |  |  |  |  |  |  | 
| 220 |  |  |  |  |  |  | # read a game @sauces in descriptive notation return a game in | 
| 221 |  |  |  |  |  |  | # long algebraic notation @moves | 
| 222 |  |  |  |  |  |  | # chess is initialized with %study if nothing usual initial chess game position | 
| 223 |  |  |  |  |  |  | # usage: | 
| 224 |  |  |  |  |  |  | #@array_of_moves=&Trad::dscrip(ini=>ref_someposition or not, | 
| 225 |  |  |  |  |  |  | #                              mov=>ref_set_of_moves) | 
| 226 |  |  |  |  |  |  |  | 
| 227 |  |  |  |  |  |  |  | 
| 228 | 0 |  |  |  |  |  | $bd=Board->new() ; | 
| 229 | 0 |  |  |  |  |  | $bd->startgame(%study) ; | 
| 230 | 0 |  |  |  |  |  | $bd->has_moved(status=>$status,ini=>'y') ; | 
| 231 |  |  |  |  |  |  |  | 
| 232 |  |  |  |  |  |  | # for debug | 
| 233 |  |  |  |  |  |  | #$bd->chessview ; | 
| 234 |  |  |  |  |  |  |  | 
| 235 |  |  |  |  |  |  | # main loop to translate notation | 
| 236 |  |  |  |  |  |  |  | 
| 237 | 0 |  |  |  |  |  | for (my $i=0; $i<=$#sauces ; $i++) { | 
| 238 |  |  |  |  |  |  |  | 
| 239 |  |  |  |  |  |  | # parse the white & black moves | 
| 240 |  |  |  |  |  |  |  | 
| 241 |  |  |  |  |  |  |  | 
| 242 |  |  |  |  |  |  |  | 
| 243 |  |  |  |  |  |  | #  $sauces[$i]=~ /(\d*\.)\s*(O|\w*\/?\d?)(-|x)([PQKNBR|O-O|O]*)(\d)?\s*(ch|e\.p\.|\([QNBR]\)|=\s*[QNBR])?\s*(O|\w*\/?\d?)(-|x)([PQKNBR|O-O|O]*)(\d)?\s*(ch|e\.p\.|\([QNBR]\)|=[QNBR])?\s*/ ; | 
| 244 |  |  |  |  |  |  | #  #                 1         2           3          4          5               6                 7            8          9           10                   11 | 
| 245 |  |  |  |  |  |  |  | 
| 246 |  |  |  |  |  |  |  | 
| 247 |  |  |  |  |  |  |  | 
| 248 | 0 |  |  |  |  |  | my $cnt=$sauces[$i]=~ tr/-x/-x/ ; | 
| 249 | 0 |  |  |  |  |  | my $pattern=qr/\s*(O|\w*\/?\d?)(-|x)([PQKNBR|O-O|O]*)(\d)?\s*(ch|e\.p\.|\([QNBR]\)|=\s*[QNBR])?/ x $cnt  ; | 
| 250 | 0 |  |  |  |  |  | $sauces[$i]=~ /(\d*\.)$pattern\s*/ ; | 
| 251 |  |  |  |  |  |  |  | 
| 252 | 0 |  |  |  |  |  | my $n=$1 ; | 
| 253 | 0 |  |  |  |  |  | my $wpiece=$2 ; | 
| 254 | 0 |  |  |  |  |  | my $waction=$3 ; | 
| 255 | 0 |  |  |  |  |  | my $wdestalpha=$4 ; | 
| 256 | 0 | 0 |  |  |  |  | my $wdestnum=$5 ? $5 : ""; | 
| 257 | 0 | 0 |  |  |  |  | my $wechec=$6 ? $6 : "" ; | 
| 258 |  |  |  |  |  |  | # for debug | 
| 259 |  |  |  |  |  |  | #  print "splitting results: $n $wpiece $waction $wdestalpha $wdestnum $wechec " ; | 
| 260 | 0 |  |  |  |  |  | mauv($bd,'White',$wpiece ,$waction ,$wdestalpha, $wdestnum ,$wechec) ; | 
| 261 |  |  |  |  |  |  |  | 
| 262 |  |  |  |  |  |  | #  my $bpiece=$7 ; | 
| 263 |  |  |  |  |  |  | #  my $baction=$8 ; | 
| 264 |  |  |  |  |  |  | #  my $bdestalpha=$9 ; | 
| 265 | 0 | 0 |  |  |  |  | my $bpiece= $cnt==2  ? $7 : ""; | 
| 266 | 0 | 0 |  |  |  |  | my $baction= $cnt==2 ? $8 : ""; | 
| 267 | 0 | 0 |  |  |  |  | my $bdestalpha= $cnt==2 ? $9 : ""; | 
| 268 | 0 | 0 |  |  |  |  | my $bdestnum=$10 ? $10 : ""; | 
| 269 | 0 | 0 |  |  |  |  | my $bechec=$11 ? $11 : "" ; | 
| 270 |  |  |  |  |  |  |  | 
| 271 |  |  |  |  |  |  | # for debug | 
| 272 | 0 | 0 |  |  |  |  | if($cnt == 2){ | 
| 273 |  |  |  |  |  |  | #  print "$bpiece $baction $bdestalpha $bdestnum $bechec \n" ; | 
| 274 | 0 |  |  |  |  |  | mauv($bd,'Black',$bpiece ,$baction ,$bdestalpha ,$bdestnum ,$bechec) ;} | 
| 275 |  |  |  |  |  |  |  | 
| 276 |  |  |  |  |  |  | #print $n ; | 
| 277 |  |  |  |  |  |  | } | 
| 278 |  |  |  |  |  |  |  | 
| 279 |  |  |  |  |  |  | # for debug | 
| 280 |  |  |  |  |  |  | #$bd->chessview ; | 
| 281 |  |  |  |  |  |  |  | 
| 282 | 0 |  |  |  |  |  | return @moves ; | 
| 283 |  |  |  |  |  |  |  | 
| 284 |  |  |  |  |  |  |  | 
| 285 |  |  |  |  |  |  | sub mauv{ | 
| 286 | 0 |  |  | 0 |  |  | my $bd=shift ; | 
| 287 | 0 |  |  |  |  |  | my ($color,$wpiece, $waction, $wdestalpha, $wdestnum ,$wechec)=@_ ; | 
| 288 |  |  |  |  |  |  |  | 
| 289 | 0 |  |  |  |  |  | @from=() ; | 
| 290 | 0 |  |  |  |  |  | @to=() ; | 
| 291 |  |  |  |  |  |  |  | 
| 292 |  |  |  |  |  |  | # find the set of pieces for the start of the moves | 
| 293 |  |  |  |  |  |  |  | 
| 294 |  |  |  |  |  |  |  | 
| 295 | 0 |  |  |  |  |  | my $fpiece= $wpiece ; | 
| 296 | 0 |  |  |  |  |  | my $roq=$wpiece .  $waction .  $wdestalpha ; | 
| 297 |  |  |  |  |  |  |  | 
| 298 | 0 | 0 |  |  |  |  | if ( $roq =~ /O-O-O/ ) { | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 299 |  |  |  |  |  |  |  | 
| 300 | 0 |  |  |  |  |  | $bd->castling(side=>'Q',status=>$status,couleur=>$color ); | 
| 301 | 0 |  |  |  |  |  | push(@moves,$roq) ; | 
| 302 | 0 |  |  |  |  |  | return ; | 
| 303 |  |  |  |  |  |  | } elsif ( $roq =~/O-O/ ) { | 
| 304 |  |  |  |  |  |  |  | 
| 305 | 0 |  |  |  |  |  | $bd->castling(side=>'K',status=>$status,couleur=>$color ); | 
| 306 | 0 |  |  |  |  |  | push(@moves,$roq) ; | 
| 307 | 0 |  |  |  |  |  | return ; | 
| 308 |  |  |  |  |  |  |  | 
| 309 |  |  |  |  |  |  | } elsif ($fpiece =~ /^[PKQRBN]$/ ) { | 
| 310 | 0 | 0 |  |  |  |  | @from=grep { $color eq 'White'? $fpiece eq $bd->{$_} :  lc $fpiece eq $bd->{$_} }  (keys %{$bd})  ; | 
|  | 0 |  |  |  |  |  |  | 
|  | 0 |  |  |  |  |  |  | 
| 311 |  |  |  |  |  |  | } else { | 
| 312 | 0 |  |  |  |  |  | $fpiece=&resolve_deb($color,$wpiece,$waction, $wdestalpha, $wdestnum ,$wechec) ; | 
| 313 |  |  |  |  |  |  | } | 
| 314 |  |  |  |  |  |  | # find the set of possible arrival cases | 
| 315 |  |  |  |  |  |  |  | 
| 316 | 0 | 0 |  |  |  |  | if (!defined ($algebra{$wdestalpha} )) { | 
| 317 | 0 |  |  |  |  |  | &resolve($bd,$color,$wpiece,$waction, $wdestalpha, $wdestnum ,$wechec) ; | 
| 318 |  |  |  |  |  |  | } else { | 
| 319 | 0 |  |  |  |  |  | my $exp= $algebra{$wdestalpha} ; | 
| 320 | 0 | 0 |  |  |  |  | my $num=$color eq 'White' ? $wdestnum : $black[$wdestnum] ; | 
| 321 | 0 |  |  |  |  |  | push @to,$exp .  $num ; | 
| 322 |  |  |  |  |  |  |  | 
| 323 | 0 | 0 |  |  |  |  | my $exp2=( ($wpiece eq 'P') ? "" : ( (length($wpiece) == 2) ? substr( $wpiece,1,1) : $wpiece  ))  .  $exp . $num ; | 
|  |  | 0 |  |  |  |  |  | 
| 324 |  |  |  |  |  |  |  | 
| 325 |  |  |  |  |  |  | } | 
| 326 |  |  |  |  |  |  | # for debug | 
| 327 |  |  |  |  |  |  | #  print  "**from ", @from , "## to ", @to ,"\n"; | 
| 328 |  |  |  |  |  |  |  | 
| 329 |  |  |  |  |  |  | # select the right move(s) | 
| 330 |  |  |  |  |  |  |  | 
| 331 |  |  |  |  |  |  |  | 
| 332 | 0 |  |  |  |  |  | foreach my $f (0..$#from) { | 
| 333 | 0 |  |  |  |  |  | foreach my $t (0..$#to) { | 
| 334 | 0 |  |  |  |  |  | my $set=[] ; | 
| 335 |  |  |  |  |  |  | ## $set contient tous les coups valides (sans echec donc) | 
| 336 | 0 | 0 |  |  |  |  | my $tpiece=$color eq 'White'  ? $fpiece : lc($fpiece) ; | 
| 337 | 0 |  |  |  |  |  | $bd->vldmov(row=>chr(vec($from[$f],1,8)), | 
| 338 |  |  |  |  |  |  | col=>chr( vec($from[$f],0,8)), | 
| 339 |  |  |  |  |  |  | piece=>$tpiece, | 
| 340 |  |  |  |  |  |  | valid=>$set) ; | 
| 341 |  |  |  |  |  |  |  | 
| 342 | 0 |  |  |  |  |  | foreach (0..$#{$set}) { | 
|  | 0 |  |  |  |  |  |  | 
| 343 | 0 | 0 |  |  |  |  | if ($set->[$_] eq  $to[$t]) { | 
| 344 |  |  |  |  |  |  | # asap la case de destination est trouvée le coup est joué | 
| 345 | 0 |  |  |  |  |  | my $hadak= uc($tpiece) . $from[$f] ; | 
| 346 | 0 | 0 |  |  |  |  | $hadak .= (defined($bd->getpiece($to[$t])) ? 'x' :'-' ) . $to[$t]; | 
| 347 | 0 |  |  |  |  |  | $hadak=~ s/P//g  ; | 
| 348 | 0 |  |  |  |  |  | ($tpiece,my $promo)=&promote($tpiece,chr(vec($to[$t],1,8)),$wechec) ; | 
| 349 | 0 |  |  |  |  |  | push(@moves,$hadak . $promo) ; | 
| 350 | 0 |  |  |  |  |  | $bd->deletepiece($from[$f]) ; | 
| 351 | 0 |  |  |  |  |  | $bd->put($tpiece, $to[$t]) ; | 
| 352 |  |  |  |  |  |  | #          for debug | 
| 353 |  |  |  |  |  |  | #	  $bd->chessview ; | 
| 354 | 0 |  |  |  |  |  | last  ; | 
| 355 |  |  |  |  |  |  | } | 
| 356 |  |  |  |  |  |  | } | 
| 357 |  |  |  |  |  |  | } | 
| 358 |  |  |  |  |  |  | } | 
| 359 |  |  |  |  |  |  |  | 
| 360 | 0 |  |  |  |  |  | return ; | 
| 361 |  |  |  |  |  |  | } | 
| 362 |  |  |  |  |  |  |  | 
| 363 |  |  |  |  |  |  | sub resolve{ | 
| 364 | 0 |  |  | 0 |  |  | my $bd=shift ; | 
| 365 | 0 |  |  |  |  |  | my ($color,$wpiece,$waction, $wdestalpha, $wdestnum ,$wechec)=@_ ; | 
| 366 |  |  |  |  |  |  |  | 
| 367 |  |  |  |  |  |  | # resout les ambiguités | 
| 368 |  |  |  |  |  |  |  | 
| 369 |  |  |  |  |  |  | # prise en passant | 
| 370 | 0 | 0 |  |  |  |  | if ($wechec eq 'e.p.') { | 
| 371 | 0 |  |  |  |  |  | my %pred=(a=>'',b=>'a',c=>'b',d=>'c',e=>'d',f=>'e',g=>'f',h=>'g') ; | 
| 372 | 0 |  |  |  |  |  | my %suiv=(a=>'b',b=>'c',c=>'d',d=>'e',e=>'f',f=>'g',g=>'h',h=>'') ; | 
| 373 | 0 |  |  |  |  |  | my @ep ; | 
| 374 |  |  |  |  |  |  |  | 
| 375 | 0 | 0 |  |  |  |  | my ( $c,$pion)= $color eq 'White'? ('Black','p'): ('White','P') ; | 
| 376 | 0 | 0 |  |  |  |  | my $cto=$color eq 'White' ? '5' : '4' ; | 
| 377 | 0 |  |  |  |  |  | my $n=$moves[$#moves] ; | 
| 378 | 0 |  |  |  |  |  | my ($col,$row)=split('',substr( $n,-2) ) ; | 
| 379 | 0 | 0 |  |  |  |  | push @to, $c eq 'White' ? $col . '3' : $col . '6' ; | 
| 380 |  |  |  |  |  |  |  | 
| 381 | 0 |  |  |  |  |  | foreach (@from) { | 
| 382 | 0 | 0 | 0 |  |  |  | if ( ($_ eq $pred{$col}.$cto ) || ($_ eq  $suiv{$col}.$cto )) { | 
| 383 | 0 |  |  |  |  |  | push @ep , $_ ; | 
| 384 |  |  |  |  |  |  | } | 
| 385 |  |  |  |  |  |  | } | 
| 386 |  |  |  |  |  |  | # ep entre 1 et 2 mais $#to=0 max | 
| 387 | 0 | 0 |  |  |  |  | if (@ep >= 1) { | 
| 388 | 0 |  |  |  |  |  | @from=@ep ; | 
| 389 |  |  |  |  |  |  | # pas propre à ce niveau mais efficace | 
| 390 |  |  |  |  |  |  |  | 
| 391 | 0 |  |  |  |  |  | $bd->deletepiece($col.$row) ; | 
| 392 | 0 |  |  |  |  |  | $bd->put($pion, $to[0]) ; | 
| 393 |  |  |  |  |  |  |  | 
| 394 | 0 |  |  |  |  |  | return ; | 
| 395 |  |  |  |  |  |  | } else { | 
| 396 | 0 |  |  |  |  |  | print "erreur sur ep", @ep, "\n" ; | 
| 397 | 0 |  |  |  |  |  | return ; | 
| 398 |  |  |  |  |  |  | } | 
| 399 |  |  |  |  |  |  | } | 
| 400 |  |  |  |  |  |  |  | 
| 401 |  |  |  |  |  |  | # ambiguité de cote K or Q | 
| 402 | 0 | 0 | 0 |  |  |  | if ($wdestalpha=~ /^[BRN]$/ && $wdestnum ne '') { | 
| 403 | 0 | 0 |  |  |  |  | my $num=($color eq 'White' ? $wdestnum : $black[$wdestnum]) ; | 
| 404 | 0 |  |  |  |  |  | push @to ,$algebra{'K' . $wdestalpha} .  $num ; | 
| 405 | 0 |  |  |  |  |  | push @to ,$algebra{'Q' . $wdestalpha} .  $num ; | 
| 406 | 0 |  |  |  |  |  | return ; | 
| 407 |  |  |  |  |  |  | } | 
| 408 |  |  |  |  |  |  |  | 
| 409 |  |  |  |  |  |  | # ambiguité prise de piece | 
| 410 | 0 | 0 | 0 |  |  |  | if ($wdestalpha=~ /^[BRNP]$/ && $waction eq 'x') { | 
| 411 | 0 | 0 |  |  |  |  | my $tpiece=$color eq 'White' ? lc($wdestalpha) :uc($wdestalpha) ; | 
| 412 | 0 |  |  |  |  |  | foreach my $loc (keys %{$bd}) { | 
|  | 0 |  |  |  |  |  |  | 
| 413 | 0 | 0 |  |  |  |  | if ($bd->{$loc} eq $tpiece ) { | 
| 414 | 0 |  |  |  |  |  | push @to,$loc; | 
| 415 |  |  |  |  |  |  | } | 
| 416 |  |  |  |  |  |  | ; | 
| 417 |  |  |  |  |  |  | } | 
| 418 |  |  |  |  |  |  |  | 
| 419 | 0 |  |  |  |  |  | return ; | 
| 420 |  |  |  |  |  |  | } | 
| 421 |  |  |  |  |  |  |  | 
| 422 |  |  |  |  |  |  | # ambiguité prise de pion | 
| 423 |  |  |  |  |  |  | #  /[QK|][BRN]P/ | 
| 424 | 0 | 0 | 0 |  |  |  | if ($wdestalpha=~ /^[BRN]P$/ && $waction eq 'x') { | 
| 425 | 0 | 0 |  |  |  |  | my $opp=$color eq 'White' ? 'p' :'P' ; | 
| 426 | 0 |  |  |  |  |  | foreach my $sq (keys %{$bd}) { | 
|  | 0 |  |  |  |  |  |  | 
| 427 | 0 |  |  |  |  |  | my $piece= $bd->{$sq} ; | 
| 428 | 0 |  |  |  |  |  | my $rk=substr($sq,0,1) ; | 
| 429 | 0 | 0 |  |  |  |  | if ($piece eq $opp ) { | 
| 430 | 0 |  |  |  |  |  | my $wx ; | 
| 431 | 0 | 0 |  |  |  |  | if ($wdestalpha=~ /^([BRN])P$/ ) { | 
| 432 | 0 |  |  |  |  |  | my $wx=$1 ; | 
| 433 | 0 |  |  |  |  |  | foreach ('Q','K') { | 
| 434 | 0 | 0 |  |  |  |  | if ($algebra{$_ . $wx} eq $rk) { | 
| 435 | 0 |  |  |  |  |  | push @to,$sq  ; | 
| 436 |  |  |  |  |  |  | } | 
| 437 |  |  |  |  |  |  | } | 
| 438 |  |  |  |  |  |  | } else { | 
| 439 | 0 |  |  |  |  |  | foreach ('Q','K') { | 
| 440 | 0 | 0 |  |  |  |  | if ($algebra{$_ } eq $rk) { | 
| 441 | 0 |  |  |  |  |  | push @to,$sq  ; | 
| 442 |  |  |  |  |  |  | } | 
| 443 |  |  |  |  |  |  | } | 
| 444 |  |  |  |  |  |  | } | 
| 445 |  |  |  |  |  |  | } | 
| 446 |  |  |  |  |  |  | } | 
| 447 | 0 |  |  |  |  |  | return ; | 
| 448 |  |  |  |  |  |  | } | 
| 449 |  |  |  |  |  |  |  | 
| 450 |  |  |  |  |  |  | # ambiguités persistantes | 
| 451 | 0 |  |  |  |  |  | print "****   ambiguity   *** \n" ; | 
| 452 | 0 |  |  |  |  |  | return ; | 
| 453 |  |  |  |  |  |  | } | 
| 454 |  |  |  |  |  |  |  | 
| 455 |  |  |  |  |  |  | sub resolve_deb { | 
| 456 |  |  |  |  |  |  |  | 
| 457 | 0 |  |  | 0 |  |  | my ($color,$wpiece,$waction, $wdestalpha, $wdestnum ,$wechec)=@_ ; | 
| 458 | 0 |  |  |  |  |  | my $truepiece ; | 
| 459 |  |  |  |  |  |  | my $side ; | 
| 460 | 0 |  |  |  |  |  | my $piece ; | 
| 461 | 0 |  |  |  |  |  | my $col ; | 
| 462 | 0 |  |  |  |  |  | my $rank ; | 
| 463 | 0 |  |  |  |  |  | my $wcol ; | 
| 464 | 0 |  |  |  |  |  | my $loc ; | 
| 465 | 0 |  |  |  |  |  | my $case ; | 
| 466 |  |  |  |  |  |  | #ambiguité sur colonne | 
| 467 |  |  |  |  |  |  |  | 
| 468 | 0 | 0 |  |  |  |  | if ($wpiece =~ /^([QRBKN])\/([1-8])$/) { | 
| 469 |  |  |  |  |  |  | # $truepiece=$1 ; | 
| 470 | 0 | 0 |  |  |  |  | ($wcol,$truepiece)=$color eq 'White' ? ($2,$1): ($black[$2],lc($1)) ; | 
| 471 | 0 |  |  |  |  |  | foreach $case (keys %{$bd}) { | 
|  | 0 |  |  |  |  |  |  | 
| 472 | 0 |  |  |  |  |  | ($rank, $col)=split(//,$case) ; | 
| 473 | 0 | 0 | 0 |  |  |  | if ( ($bd->{$case} eq $truepiece)  && ($col == $wcol)  ) { | 
| 474 | 0 |  |  |  |  |  | push @from,$case ; | 
| 475 |  |  |  |  |  |  | } | 
| 476 |  |  |  |  |  |  | } | 
| 477 | 0 |  |  |  |  |  | return ($truepiece) ; | 
| 478 |  |  |  |  |  |  | } | 
| 479 |  |  |  |  |  |  |  | 
| 480 |  |  |  |  |  |  | #ambiguité sur queen side  & king side | 
| 481 |  |  |  |  |  |  | #  ex  N=e4  et N =g8 => QN=e4 et KN=g8  e | 
| 482 |  |  |  |  |  |  | # pb avec 3 pieces ?? | 
| 483 |  |  |  |  |  |  |  | 
| 484 | 0 | 0 |  |  |  |  | if ($wpiece =~ /(^[QK])([QRBN]$)/ ) { | 
| 485 | 0 | 0 |  |  |  |  | $truepiece=$color eq 'White' ? $2:lc($2) ; | 
| 486 | 0 |  |  |  |  |  | $side=$1 ; | 
| 487 | 0 |  |  |  |  |  | my $i=0 ; | 
| 488 | 0 |  |  |  |  |  | my @loc ; | 
| 489 |  |  |  |  |  |  |  | 
| 490 | 0 |  |  |  |  |  | foreach $case (keys %{$bd} ) { | 
|  | 0 |  |  |  |  |  |  | 
| 491 | 0 | 0 |  |  |  |  | if ($bd->{$case} eq $truepiece ) { | 
| 492 | 0 |  |  |  |  |  | $loc[$i]= $case ;$i++ ; | 
|  | 0 |  |  |  |  |  |  | 
| 493 |  |  |  |  |  |  | } | 
| 494 |  |  |  |  |  |  | } | 
| 495 |  |  |  |  |  |  |  | 
| 496 | 0 | 0 |  |  |  |  | if ($#loc < 2) { | 
| 497 | 0 | 0 |  |  |  |  | push @from,( $side eq 'Q' ? ( ( substr($loc[0],0,1) lt substr($loc[1],0,1)) ? $loc[0]: $loc[1] ) | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 498 |  |  |  |  |  |  | : ( ( substr($loc[0],0,1) gt substr($loc[1],0,1)) ? $loc[0]: $loc[1] )) ;} | 
| 499 |  |  |  |  |  |  | else { | 
| 500 | 0 |  |  |  |  |  | print " ambiguity :  piece number gt  à 2 : $#loc \n  " ; | 
| 501 |  |  |  |  |  |  | } | 
| 502 |  |  |  |  |  |  | } | 
| 503 |  |  |  |  |  |  |  | 
| 504 | 0 |  |  |  |  |  | return ($truepiece) ; | 
| 505 |  |  |  |  |  |  |  | 
| 506 |  |  |  |  |  |  | # ambiguités peristantes = not solved | 
| 507 |  |  |  |  |  |  |  | 
| 508 | 0 |  |  |  |  |  | print "ambiguity at start of the mpve \n" ; | 
| 509 |  |  |  |  |  |  |  | 
| 510 | 0 |  |  |  |  |  | return ; | 
| 511 |  |  |  |  |  |  | } | 
| 512 |  |  |  |  |  |  |  | 
| 513 |  |  |  |  |  |  |  | 
| 514 |  |  |  |  |  |  |  | 
| 515 |  |  |  |  |  |  | sub promote{ | 
| 516 |  |  |  |  |  |  | #check if the pawn get the last rank | 
| 517 |  |  |  |  |  |  | # usage (piece chosen , = piece chosen)=promote(pawn,row location,piece chosen) | 
| 518 |  |  |  |  |  |  | # dual syntax for the chosen piece X: =X or (X) | 
| 519 | 0 |  |  | 0 |  |  | my $tpiece=shift ; | 
| 520 | 0 |  |  |  |  |  | my $row=shift ; | 
| 521 | 0 |  |  |  |  |  | my $wechec=shift ; | 
| 522 |  |  |  |  |  |  |  | 
| 523 | 0 | 0 | 0 |  |  |  | if( $tpiece eq 'P' && $row==8){ | 
| 524 |  |  |  |  |  |  | # retrieve the piece to promote | 
| 525 | 0 |  |  |  |  |  | $wechec=~ s/[\(|=]\s*([QNBR])\s*\)?/$1/ ; | 
| 526 | 0 |  |  |  |  |  | return ($wechec,'='. uc($wechec) ) ;} | 
| 527 |  |  |  |  |  |  |  | 
| 528 | 0 | 0 | 0 |  |  |  | if( $tpiece eq 'p' && $row==1){ | 
| 529 |  |  |  |  |  |  | # retrieve the piece to promote | 
| 530 | 0 |  |  |  |  |  | $wechec=~ s/[\(|=]\s*([QNBR])\s*\)?/$1/ ; | 
| 531 | 0 |  |  |  |  |  | return (lc $wechec,'='. uc($wechec) ) ;} | 
| 532 |  |  |  |  |  |  | # not a pawn to promote , nothing to do | 
| 533 | 0 |  |  |  |  |  | return ($tpiece,"") ; | 
| 534 |  |  |  |  |  |  | } | 
| 535 |  |  |  |  |  |  | } | 
| 536 |  |  |  |  |  |  | 1 ; |