%! % Needs: http://homepages.di.fc.ul.pt/~jpn/gv/tabs/chessfont.zip % whichzips to a TTF file which you move into /usr/share/fonts/truetype % See: http://homepages.di.fc.ul.pt/~jpn/gv/tabs/chess-template.eps % by Joao Pedro Neto 2016 % In JS: https://github.com/jhlywa/chess.js/blob/master/README.md %---------------- Constants ------------------- /Chess.dx 40 def % the size of the square /Chess.markersize 0.7 def % relative size of letters inside the squares %---------------- Functions ------------------- /PlaceAt { % call: row col PlaceAt 2 dict begin /col exch def /row exch def Chess.dx col mul Chess.dx row mul moveto end } bind def /Square { % call: row col Square 2 dict begin /col exch def /row exch def col row add 2 mod 0 eq { row col Black } { row col White } ifelse end } bind def /Black { % call: row col Black 2 dict begin /col exch def /row exch def row col PlaceAt (+) show end } bind def /White { % call: row col White 2 dict begin /col exch def /row exch def row col PlaceAt (*) show end } bind def /PawnW { % call: row col PawnW 5 dict begin /col exch def /row exch def col row add 2 mod 0 eq { row col PlaceAt (P) show } { row col PlaceAt (p) show } ifelse end } bind def /PawnB { % call: row col PawnB 2 dict begin /col exch def /row exch def col row add 2 mod 0 eq { row col PlaceAt (O) show } { row col PlaceAt (o) show } ifelse end } bind def /KnightW { % call: row col KnightW 2 dict begin /col exch def /row exch def col row add 2 mod 0 eq { row col PlaceAt (H) show } { row col PlaceAt (h) show } ifelse end } bind def /KnightB { % call: row col KnightB 2 dict begin /col exch def /row exch def col row add 2 mod 0 eq { row col PlaceAt (J) show } { row col PlaceAt (j) show } ifelse end } bind def /BishopW { % call: row col BishopW 2 dict begin /col exch def /row exch def col row add 2 mod 0 eq { row col PlaceAt (B) show } { row col PlaceAt (b) show } ifelse end } bind def /BishopB { % call: row col BishopB 2 dict begin /col exch def /row exch def col row add 2 mod 0 eq { row col PlaceAt (N) show } { row col PlaceAt (n) show } ifelse end } bind def /RookW { % call: row col RookW 2 dict begin /col exch def /row exch def col row add 2 mod 0 eq { row col PlaceAt (R) show } { row col PlaceAt (r) show } ifelse end } bind def /RookB { % call: row col RookB 2 dict begin /col exch def /row exch def col row add 2 mod 0 eq { row col PlaceAt (T) show } { row col PlaceAt (t) show } ifelse end } bind def /QueenW { % call: row col QueenW 2 dict begin /col exch def /row exch def col row add 2 mod 0 eq { row col PlaceAt (Q) show } { row col PlaceAt (q) show } ifelse end } bind def /QueenB { % call: row col QueenB 2 dict begin /col exch def /row exch def col row add 2 mod 0 eq { row col PlaceAt (W) show } { row col PlaceAt (w) show } ifelse end } bind def /KingW { % call: row col KingW 2 dict begin /col exch def /row exch def col row add 2 mod 0 eq { row col PlaceAt (K) show } { row col PlaceAt (k) show } ifelse end } bind def /KingB { % call: row col KingB 2 dict begin /col exch def /row exch def col row add 2 mod 0 eq { row col PlaceAt (L) show } { row col PlaceAt (l) show } ifelse end } bind def /Board { % call: position (<- array) flip (<- bool) Board 20 dict begin /flip exch def /pos exch def /cols 8 def /rows 8 def 1 1 rows { % for each row /i exch def flip { % write row coords i -0.25 [( 0)( 1)( 2)( 3)( 4)( 5)( 6)( 7)( 8)] 9 i sub get Label } { i -0.25 [( 0)( 1)( 2)( 3)( 4)( 5)( 6)( 7)( 8)] i get Label } ifelse /ChessPiece findfont Chess.dx scalefont setfont i 0 PlaceAt (/) show 1 1 cols { % for each column /ChessPiece findfont Chess.dx scalefont setfont /j exch def % get (i,j) from the board-array index pos i 1 sub cols mul j 1 sub add get /piece exch def flip { 9 rows i sub 1 add sub 9 j sub } { rows i sub 1 add j } ifelse piece 0 eq { Square } if piece 1 eq { PawnW } if piece -1 eq { PawnB } if piece 2 eq { KnightW } if piece -2 eq { KnightB } if piece 3 eq { BishopW } if piece -3 eq { BishopB } if piece 4 eq { RookW } if piece -4 eq { RookB } if piece 5 eq { QueenW } if piece -5 eq { QueenB } if piece 6 eq { KingW } if piece -6 eq { KingB } if } for i cols 1 add PlaceAt (\\) show 1 1 cols { % draw upper and bottom lines /j exch def 0 j PlaceAt (_) show rows 1 add j PlaceAt (-) show flip { % write column coords 0 j [(a)(b)(c)(d)(e)(f)(g)(h)] 8 j sub get Label } { 0 j [(a)(b)(c)(d)(e)(f)(g)(h)] j 1 sub get Label } ifelse } for } for end } bind def /Label { % call: row col string Label 10 dict begin [ /s /c /r ] { exch def } forall % /s exch def /c exch def /r exch def gsave Chess.dx 4 div Chess.dx 5 div translate /coordsize Chess.dx 0.55 mul def /Courier findfont coordsize scalefont setfont r 9 gt { % if the number is 10 or greater /basefont /Courier findfont def % it will condense font to fit size basefont [coordsize 2 div 0 0 coordsize 0 0] makefont setfont r c 0.4 add PlaceAt } { r c PlaceAt } ifelse s show grestore end } bind def /space_to_centre { % usage: (string) space_to_centre 10 dict begin /str exch def gsave gsave str false charpath flattenpath pathbbox grestore % llx lly urx ury [ /ury /urx /lly /llx ] { exch def } forall % I don't understand this 0.45 stuff - but it seems to work Chess.dx 0.45 mul urx llx sub 0.45 mul sub % delta_x Chess.dx 0.40 mul ury lly sub 0.45 mul sub % delta_x delta_y grestore end } bind def /Marker { % call: j i grey_ratio boolean_charpath string_1_char Marker 10 dict begin [ /s /b /g /i /j ] { exch def } forall gsave g setgray /insidesize Chess.dx Chess.markersize mul def /basefont /Helvetica-Bold findfont def basefont [ insidesize s length 0.6 exp div 0 0 insidesize 0 0 ] makefont setfont % now narrowed s space_to_centre translate j i PlaceAt b { Chess.dx 0.015 mul setlinewidth s true charpath gsave 1 setgray fill grestore stroke } { s show } ifelse grestore end } bind def %-------------------------------------------------------------------------- /fen2board { % useage: fenstr flip fen2board 10 dict begin /flip exch def /fenstr exch def % /char2num << (p) -1 (n) -2 (b) -3 (r) -4 (q) -5 (k) -6 % (P) 1 (N) 2 (B) 3 (R) 4 (Q) 5 (K) 6 (1) 0 >> def /char2num << 112 -1 110 -2 98 -3 114 -4 113 -5 107 -6 80 1 78 2 66 3 82 4 81 5 75 6 49 0 >> def /a 64 array def /i 0 def /istr 0 def /active ( ) def fenstr { /c exch def c 32 eq { exit } if c 47 eq { % skip / } { c 50 ge c 56 le and { % its 2..8 /n c 48 sub def { a i 0 put /i i 1 add def /n n 1 sub def n 1 lt { exit } if } loop } { % else its a character in the dict char2num a i char2num c get put /i i 1 add def } ifelse } ifelse /istr istr 1 add def } forall a flip Board fenstr length istr 1 add gt { /active fenstr istr 1 add get def active 98 eq { flip { 1 } { 8 } ifelse 9.1 (B) Label } { flip { 8 } { 1 } ifelse 9.1 (W) Label } ifelse } if end } bind def