-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpschess_compact.ps
More file actions
executable file
·8 lines (7 loc) · 22.1 KB
/
pschess_compact.ps
File metadata and controls
executable file
·8 lines (7 loc) · 22.1 KB
1
2
3
4
5
6
7
8
%!PS-Adobe-2.0
% Nicolas Seriot
% 2024-03-23
% https://github.com/nst/PSChess
% https://seriot.ch/projects/pschess.html
% gs -DNOSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile="%d.pdf" pschess_compact.ps
/D{def}def/B{GameState(BOARD)}D/F{forall}D/g{getinterval}D/X{exch}D/G{get}D/db{dict begin}D/e{end}D/CreateBoard_b_{(rnbqkbnrpppppppp................................PPPPPPPPRNBQKBNR)sds}D/_board_PrintBoard{2 db/b X D()= b 0 8 g = b 8 8 g = b 16 8 g = b 24 8 g = b 32 8 g = b 40 8 g = b 48 8 g = b 56 8 g =()= e}D/sds{dup length string cvs}D/_c_IsValidCoordinate_b_{/cr X D/ret false D cr length 2 eq{/i cr ci D i iibr{/ret true D}if}if ret}D/_index_Col_a-h_{/c( )sds D 1 db/i X D c 0 i 8 mod 97 add put e c}D/_index_Row_1-8_{1 db/i X D 8 i 8 idiv sub e}D/ci{3 db/cs X D/col{cs 0 G 97 sub}bind D/row{7 cs 1 G 49 sub sub}bind D col 0 lt{(invalid col)==}if col 7 gt{(invalid col)==}if row 0 lt{(invalid row)==}if row 7 gt{(invalid row)==}if row 8 mul col add e}D/_index_Coord_c_{2 db/i_ X D i_ iibr false eq{(-- BAD INDEX:)print i_ == quit}if/col i_ 8 mod 97 add D/row 8 i_ 8 idiv sub 48 add D/c__ 2 string D c__ 0 col put c__ 1 row put c__ e}D/bip{1 g}D/bcp{3 db/c X D/board X D board c ci bip e}D/iibr{dup 0 ge X 63 le and}D/hec{5 db/a2 X D/a1 X D/r true D a1 length a2 length eq{0 1 a1 length 1 sub{/i X D a1 i G a2 i G ne{/r false D exit}if}for}{/r false D}ifelse r e}D/dlc{3 db/p X D{(.rnbkqp)p search{pop pop pop p exit}{pop}ifelse(RNBKQPX)p search{pop pop pop/low( )D low 0 p 0 G 32 add put low exit}{pop}ifelse(ERROR: piece unknown: )print p == null exit}loop e}D/_board_piece_PieceIndex_i_{5 db/p X D/b X D/pIndex null D b p search{/pIndex X length D pop pop}{pop}ifelse pIndex e}D/_piece_IsWhite_b_{(RNBKQP)X search{pop pop pop true}{pop false}ifelse}D/_piece_IsBlack_b_{(rnbkqp)X search{pop pop pop true}{pop false}ifelse}D/_piece_IsEmpty_b_{(.)eq}D/dr{2 db/a1 X D/a2 a1 length array D 0 1 a1 length 1 sub{/i X D a2 a1 length i sub 1 sub a1 i G put}for a2 e}D/NewGame{/GameState<<(BOARD)()(CURRENT_PLAYER)(white)(LAST_MOVE)()(WHITE_DID_CASTLE)false(BLACK_DID_CASTLE)false(CAPTURED_BY_BLACK)(................)sds(CAPTURED_BY_WHITE)(................)sds(LAST_MESSAGE)()(ENDING_HAS_BEGUN)false(EN_PASSANT_WHITE_CANDIDATE)null(EN_PASSANT_BLACK_CANDIDATE)null(PLAYER_TURN_MESSAGE)()>>D GameState(BOARD)CreateBoard_b_ put GameState(LAST_PLAYER)( )sds put GameState(LAST_MOVE)( )sds put GameState(LAST_MESSAGE)(white turn )sds put GameState(ENDING_HAS_BEGUN)false put}D/PrintBoardAndGameState{2 db/b B G D()= b 0 8 g print( )print GameState(LAST_MOVE)G = b 8 8 g print( )print B G _b_Eval_score_ = b 16 8 g = b 24 8 g print( )print GameState(CAPTURED_BY_BLACK)G = b 32 8 g print( ) print GameState(CAPTURED_BY_WHITE)G = b 40 8 g = b 48 8 g print( ) print GameState(LAST_MESSAGE)G = b 56 8 g print( ) print GameState(PLAYER_TURN_MESSAGE)G =()= e}D/_p_a_AddToCaptured{5 db/a X D/p X D 0 1 a length{/i X D a i 1 g(.)eq{a i p sds putinterval exit}if}for e}D/ChangePlayer_playerColor_{/s{GameState(CURRENT_PLAYER)G _whiteOrBlack_Invert_s_}D GameState(CURRENT_PLAYER)s put GameState(CURRENT_PLAYER)G}D/_board_index_IsWhite_b_{X bip _piece_IsWhite_b_}D/_board_index_IsBlack_b_{X bip _piece_IsBlack_b_}D/_board_index_IsEmpty_b_{X bip _piece_IsEmpty_b_}D/_movesIntsOrNulls_MovesList_a_{5 db/m X D/a m length array D/n 0 D 0 1 m length 1 sub{/i X D/o m i G D o 1 eq{a n i put/n n 1 add D}if}for a 0 n g e}D/ao{12 db/ret false D/toIndex X D/fromIndex X D/board X D/fromPiece board fromIndex bip D/toPiece board toIndex bip D/fromIsWhite fromPiece _piece_IsWhite_b_ D/toIsWhite toPiece _piece_IsWhite_b_ D/fromIsBlack fromPiece _piece_IsBlack_b_ D/toIsBlack toPiece _piece_IsBlack_b_ D fromIsWhite toIsBlack and fromIsBlack toIsWhite and or e}D/asc{12 db/toIndex X D/fromIndex X D/board X D/fromPiece board fromIndex bip D/toPiece board toIndex bip D/fromIsWhite fromPiece _piece_IsWhite_b_ D/toIsWhite toPiece _piece_IsWhite_b_ D/fromIsBlack fromPiece _piece_IsBlack_b_ D/toIsBlack toPiece _piece_IsBlack_b_ D fromIsWhite toIsWhite and fromIsBlack toIsBlack and or e}D/DirectionsForPiece<</N -8 D/E 1 D/S 8 D/W -1 D(P)[N N N add N W add N E add](p)[S S S add S E add S W add](n)[N N E add add E N E add add E S E add add S S E add add S S W add add W S W add add W N W add add N N W add add](b)[N E add S E add S W add N W add](r)[N E S W](q)[N E S W N E add S E add S W add N W add](k)[N E S W N E add S E add S W add N W add](.)[]>>D/bcvm{/legalMoves 64 array D 8 db/fromCoord X D/board X D/fromIndex fromCoord ci D/p board fromIndex 1 g D DirectionsForPiece p p(P)ne{dlc}if G{/offset X D /lastIndex offset 0 gt{63}{0}ifelse D /currentCol fromIndex _index_Col_a-h_ D/currentRow fromIndex _index_Row_1-8_ D fromIndex offset lastIndex{/toIndex X D fromIndex toIndex eq not{toIndex iibr not{exit}if/toCol toIndex _index_Col_a-h_ D/toRow toIndex _index_Row_1-8_ D currentCol(a)eq toCol(g)eq and{exit}if currentCol(a)eq toCol(h)eq and{exit}if currentCol(b)eq toCol(h)eq and{exit}if currentRow(1)eq toRow(8)eq and{exit}if currentCol(g)eq toCol(a)eq and{exit}if currentCol(h)eq toCol(a)eq and{exit}if currentCol(h)eq toCol(b)eq and{exit}if currentRow(8)eq toRow(1)eq and{exit}if p(p)eq p(P)eq or{currentCol toCol ne{/isEnPassantWhite false D/whiteEP GameState(EN_PASSANT_WHITE_CANDIDATE)G D whiteEP null ne{toRow 3 eq toCol whiteEP ci _index_Col_a-h_ eq and{/isEnPassantWhite true D}if}if /isEnPassantBlack false D/blackEP GameState(EN_PASSANT_BLACK_CANDIDATE)G D blackEP null ne{toRow 6 eq toCol blackEP ci _index_Col_a-h_ eq and{/isEnPassantBlack true D}if}if/isEnPassant isEnPassantWhite isEnPassantBlack or D board fromIndex toIndex ao not isEnPassant not and{exit}if}if toRow currentRow sub abs 2 eq{/pIsWhite p(P)eq D currentRow pIsWhite{2}{7}ifelse ne{exit}if board fromIndex 8 pIsWhite{sub}{add}ifelse bip _piece_IsEmpty_b_ not{exit}if}if currentCol toCol eq{board toIndex bip _piece_IsEmpty_b_ not{exit}if}if}if board fromIndex toIndex asc{exit}if legalMoves toIndex 1 put board fromIndex toIndex ao{exit}if(brq)p dlc search{pop pop pop}{pop exit}ifelse/currentCol toIndex _index_Col_a-h_ D/currentRow toIndex _index_Row_1-8_ D}if}for}F GameState(BLACK_DID_CASTLE)G not p(k)eq and fromCoord(e8)eq and{fromCoord(e8)eq board 4 4 g(k..r)eq and{legalMoves fromIndex 2 add 1 put}if fromCoord(e8)eq board 0 5 g(r...k)eq and{legalMoves fromIndex -2 add 1 put}if}if GameState(WHITE_DID_CASTLE)G not p(K)eq and fromCoord(e1)eq and{fromCoord(e1)eq board 60 4 g(K..R)eq and{legalMoves fromIndex 2 add 1 put}if fromCoord(e1)eq board 56 5 g(R...K)eq and{legalMoves fromIndex -2 add 1 put}if}if e legalMoves}D/_board_MaterialValue_white_black_{5 db/b X D/whiteValue 0 D/blackValue 0 D 0 1 63{/i X D/p b i 1 g D WhitePieceValueDict p known{/whiteValue whiteValue WhitePieceValueDict p G add D}if BlackPieceValueDict p known{/blackValue blackValue BlackPieceValueDict p G add D}if}for whiteValue blackValue e}D/M{/canMove true D/msg(-)D/didActuallyMove false D 10 db/isDry X D/toCoord X D/fromCoord X D/brd X D fromCoord ci iibr not toCoord ci iibr not or{false 64 array(bad coords)false quit}if/fromPiece brd fromCoord bcp D/toPiece brd toCoord bcp D/fromIndex{fromCoord ci}D/toIndex{toCoord ci}D/a brd fromCoord bcvm D/i toCoord ci D a fromCoord ci 3 put{a i G null eq fromCoord toCoord eq or{/canMove false D/msg(invalid move)D a toCoord ci 2 put exit}if GameState(CURRENT_PLAYER)G(white)hec fromPiece _piece_IsBlack_b_ and{/canMove false D/msg(ERROR: white turn)D exit}if GameState(CURRENT_PLAYER)G(black)hec fromPiece _piece_IsWhite_b_ and{/canMove false D/msg(ERROR: black turn)D exit}if isDry{exit}if/futureBoard brd sds D futureBoard toIndex futureBoard fromCoord bcp putinterval futureBoard fromIndex(.)putinterval fromPiece _piece_IsWhite_b_ futureBoard(white)kic and{/canMove false D/msg(white checked)D a toCoord ci 2 put exit}if fromPiece _piece_IsBlack_b_ futureBoard(black)kic and{/canMove false D/msg(black checked)D a toCoord ci 2 put exit}if/a 64 array D a fromCoord ci 3 put a toCoord ci 1 put/fromPiece brd fromCoord bcp D/toPiece brd toCoord bcp D/doCapture fromPiece _piece_IsBlack_b_ toPiece _piece_IsWhite_b_ and fromPiece _piece_IsWhite_b_ toPiece _piece_IsBlack_b_ and or D doCapture{fromPiece _piece_IsBlack_b_{toPiece GameState(CAPTURED_BY_BLACK)G _p_a_AddToCaptured}if fromPiece _piece_IsWhite_b_{toPiece GameState(CAPTURED_BY_WHITE)G _p_a_AddToCaptured}if}if/fromCol fromCoord ci _index_Col_a-h_ D/toCol toCoord ci _index_Col_a-h_ D/toRow toCoord ci _index_Row_1-8_ D [[(EN_PASSANT_BLACK_CANDIDATE)(CAPTURED_BY_WHITE)(P)6][(EN_PASSANT_WHITE_CANDIDATE)(CAPTURED_BY_BLACK)(p)4]]{/ccfp X D/candidateKey ccfp 0 G D/captureKey ccfp 1 G D/fromPawn ccfp 2 G D/toRowTarG ccfp 3 G D/candidate GameState candidateKey G D candidate null ne fromPiece fromPawn eq and{/candidateCol candidate ci _index_Col_a-h_ D/candidateRow candidate ci _index_Row_1-8_ D candidate 0 G fromCol 0 G sub abs 1 eq toRow toRowTarG eq and toCol candidateCol eq and{brd candidate bcp GameState captureKey G _p_a_AddToCaptured brd candidate ci(.)putinterval a fromCoord ci 3 put a toCoord ci 1 put}if}if}F GameState(EN_PASSANT_WHITE_CANDIDATE)null put GameState(EN_PASSANT_BLACK_CANDIDATE)null put fromPiece(p)eq fromCoord ci _index_Row_1-8_ 7 eq and toCoord ci _index_Row_1-8_ 5 eq and{GameState(EN_PASSANT_BLACK_CANDIDATE)toCoord put GameState(EN_PASSANT_WHITE_CANDIDATE)null put}if fromPiece(P)eq fromCoord ci _index_Row_1-8_ 2 eq and toCoord ci _index_Row_1-8_ 4 eq and{GameState(EN_PASSANT_WHITE_CANDIDATE)toCoord put GameState(EN_PASSANT_BLACK_CANDIDATE)null put}if /JustCastled false def GameState(BLACK_DID_CASTLE)G not fromPiece(k)eq and fromCoord(e8)eq and toCoord(c8)eq and{brd(black)[2 3 4]icoc not{brd 0(..kr)putinterval GameState(BLACK_DID_CASTLE)true put /JustCastled true def}{/canMove false D/msg(ERR: black checked)D exit}ifelse}if GameState(BLACK_DID_CASTLE)G not fromPiece(k)eq and fromCoord(e8)eq and toCoord(g8)eq and{brd(black)[4 5 6]icoc not{brd 4(rk..)putinterval GameState(BLACK_DID_CASTLE)true put /JustCastled true def}{/canMove false D/msg(ERR: black checked)D exit}ifelse}if GameState(WHITE_DID_CASTLE)G not fromPiece(K)eq and fromCoord(e1)eq and toCoord(g1)eq and{brd(white)[60 61 62]icoc not{brd 60(.RK.)putinterval GameState(BLACK_DID_CASTLE)true put /JustCastled true def}{/canMove false D/msg(ERR: white checked)D exit}ifelse}if GameState(WHITE_DID_CASTLE)G not fromPiece(K)eq and fromCoord(e1)eq and toCoord(c1)eq and{brd(white)[58 59 60]icoc not{brd 56(..KR)putinterval GameState(BLACK_DID_CASTLE)true put /JustCastled true def}{/canMove false D/msg(ERR: white checked)D exit}ifelse}if JustCastled not {/p B G fromCoord bcp D brd toIndex p putinterval brd fromIndex(.)putinterval}if /toPiece brd toCoord bcp D toPiece(P)eq toIndex _index_Row_1-8_ 8 eq and{brd toIndex(Q)putinterval}if toPiece(p)eq toIndex _index_Row_1-8_ 1 eq and{brd toIndex(q)putinterval}if/didActuallyMove true D B brd sds put/whiteQueenOnBoard brd(Q)_board_piece_PieceIndex_i_ null ne D/blackQueenOnBoard brd(q)_board_piece_PieceIndex_i_ null ne D/noMoreQueens whiteQueenOnBoard not blackQueenOnBoard not and D brd _board_MaterialValue_white_black_/blackValue X D/whiteValue X D/eingHasBegun whiteQueenOnBoard 21000 whiteValue le and blackQueenOnBoard 21000 blackValue le and or noMoreQueens or D GameState(ENDING_HAS_BEGUN)eingHasBegun put exit}loop didActuallyMove{/s( )D s 0 GameState(CURRENT_PLAYER)G putinterval s 6 fromCoord putinterval s 9 toCoord putinterval GameState(LAST_MOVE)s put}{/s( )D s 5 fromCoord putinterval s 8 toCoord putinterval GameState(LAST_MOVE)s put}ifelse GameState(LAST_MESSAGE)msg put canMove a msg didActuallyMove e{ChangePlayer_playerColor_ pop}if/playerTurnMessage( )D playerTurnMessage 0(xxxxx turn)putinterval playerTurnMessage 0 GameState(CURRENT_PLAYER)G putinterval GameState(PLAYER_TURN_MESSAGE)playerTurnMessage put}D/_board_whiteOrBlack_LegalMoves_d_{15 db/whiteOrBlack X D/board X D/legalMovesDict << >> D whiteOrBlack(black)eq not whiteOrBlack(white)eq not and{(-- bad param, need 'white' or 'black')== quit}if/whiteTrueBlackFalse whiteOrBlack(white)hec D 0 1 63{/i X D/p board i 1 g D/fc i _index_Coord_c_ D p _piece_IsWhite_b_ whiteTrueBlackFalse and p _piece_IsBlack_b_ whiteTrueBlackFalse not and or{/moves board fc bcvm D moves{1 eq{legalMovesDict fc moves put exit}if}F}if}for legalMovesDict e}D/_whiteOrBlack_Invert_s_{/wb X D{wb(white)eq{(black)exit}if wb(black)eq{(white)exit}if(-- bad param, need 'white' or 'black')== quit}loop}D/iic{5 db/idx X D/whiteOrBlack X D/board X D board whiteOrBlack [idx ]icoc e}D/icoc{10 db/indices X D/whiteOrBlack X D/board X D whiteOrBlack(white)hec not whiteOrBlack(black)hec not and{(-- bad param, need 'white' or 'black')== quit}if/opponentMovesDict board whiteOrBlack _whiteOrBlack_Invert_s_ _board_whiteOrBlack_LegalMoves_d_ D/indicesContainOneChecked false D opponentMovesDict{/v X D/k X D indices{/ii X D v ii G 1 eq{/indicesContainOneChecked true D exit exit}if}F}F indicesContainOneChecked e}D/kic{5 db/whiteOrBlack X D/board X D whiteOrBlack(white)hec not whiteOrBlack(black)hec not and{(-- bad param, need 'white' or 'black')== quit}if/ownKing whiteOrBlack(white)hec{(K)}{(k)}ifelse D/ownKingIndex{board ownKing _board_piece_PieceIndex_i_}D ownKingIndex null ne{board whiteOrBlack ownKingIndex iic}{false}ifelse e}D/WhitePieceValueDict <<(P)100(N)320(B)330(R)500(Q)900(K)20000(.)0 >> D/BlackPieceValueDict << >> D/WhitePieceSquareDict<<(P)[0 0 0 0 0 0 0 0 50 50 50 50 50 50 50 50 10 10 20 30 30 20 10 10 5 5 10 25 25 10 5 5 0 0 0 20 20 0 0 0 5 -5 -10 0 0 -10 -5 5 5 10 10 -20 -20 10 10 5 0 0 0 0 0 0 0 0 ](N)[-50 -40 -30 -30 -30 -30 -40 -50 -40 -20 0 0 0 0 -20 -40 -30 0 10 15 15 10 0 -30 -30 5 15 20 20 15 5 -30 -30 0 15 20 20 15 0 -30 -30 5 10 15 15 10 5 -30 -40 -20 0 5 5 0 -20 -40 -50 -40 -30 -30 -30 -30 -40 -50 ](B)[-20 -10 -10 -10 -10 -10 -10 -20 -10 0 0 0 0 0 0 -10 -10 0 5 10 10 5 0 -10 -10 5 5 10 10 5 5 -10 -10 0 10 10 10 10 0 -10 -10 10 10 10 10 10 10 -10 -10 5 0 0 0 0 5 -10 -20 -10 -10 -10 -10 -10 -10 -20 ](R)[0 0 0 0 0 0 0 0 5 10 10 10 10 10 10 5 -5 0 0 0 0 0 0 -5 -5 0 0 0 0 0 0 -5 -5 0 0 0 0 0 0 -5 -5 0 0 0 0 0 0 -5 -5 0 0 0 0 0 0 -5 0 0 0 5 5 0 0 0 ](Q)[-20 -10 -10 -5 -5 -10 -10 -20 -10 0 0 0 0 0 0 -10 -10 0 5 5 5 5 0 -10 -5 0 5 5 5 5 0 -5 0 0 5 5 5 5 0 -5 -10 5 5 5 5 5 0 -10 -10 0 5 0 0 0 0 -10 -20 -10 -10 -5 -5 -10 -10 -20 ](K)[-30 -40 -40 -50 -50 -40 -40 -30 -30 -40 -40 -50 -50 -40 -40 -30 -30 -40 -40 -50 -50 -40 -40 -30 -30 -40 -40 -50 -50 -40 -40 -30 -20 -30 -30 -40 -40 -30 -30 -20 -10 -20 -20 -20 -20 -20 -20 -10 20 20 0 0 0 0 20 20 20 30 10 0 0 10 30 20 ](X)[-50 -40 -30 -20 -20 -30 -40 -50 -30 -20 -10 0 0 -10 -20 -30 -30 -10 20 30 30 20 -10 -30 -30 -10 30 40 40 30 -10 -30 -30 -10 30 40 40 30 -10 -30 -30 -10 20 30 30 20 -10 -30 -30 -30 0 0 0 0 -30 -30 -50 -30 -30 -30 -30 -30 -30 -50 ]>>D/BlackPieceSquareDict<<>>D/initPiecesDicts{WhitePieceValueDict{/v X D/k X D BlackPieceValueDict k( )cvs dlc v put}F WhitePieceSquareDict{/v X D/k X D BlackPieceSquareDict k( )cvs dlc v dr put}F}D initPiecesDicts/_b_Eval_score_{/b X D 5 db/totalScore 0 D 0 1 63{/i X D/p b i 1 g D GameState(ENDING_HAS_BEGUN)G{p(k)eq{/p(x)D}if p(K)eq{/p(X)D}if}if p(.)ne{/whiteValueScore WhitePieceValueDict p known{WhitePieceValueDict p G}{0}ifelse D/whiteSquareScore WhitePieceSquareDict p known{WhitePieceSquareDict p G i G}{0}ifelse D/blackValueScore BlackPieceValueDict p known{BlackPieceValueDict p G}{0}ifelse D/blackSquareScore BlackPieceSquareDict p known{BlackPieceSquareDict p G i G}{0}ifelse D/totalScore totalScore whiteValueScore add whiteSquareScore add blackValueScore sub blackSquareScore sub D}if}for totalScore e}D/_player_board_CanPlay_b_{/brd X D/player X D 5 db/canPlay false D brd player _board_whiteOrBlack_LegalMoves_d_{/v X D/k X D/fromCoord k( )cvs D/movesList v _movesIntsOrNulls_MovesList_a_ D movesList{/i X D/toCoord i _index_Coord_c_ D/futureBoard brd sds D/p futureBoard fromCoord bcp D futureBoard i p putinterval futureBoard fromCoord ci(.)putinterval futureBoard player kic not{/canPlay true D}if canPlay{exit}if}F canPlay{exit}if}F canPlay e}D/mae{/brd X D/player X D/movesAndScores << >> D 5 db/whiteArePlaying player(white)eq D/m brd player _board_whiteOrBlack_LegalMoves_d_ D/highestScore -1000000 D/lowestScore 1000000 D/highestMove null D/lowestMove null D m{/v X D/k X D/fromCoord k( )cvs D/movesList v _movesIntsOrNulls_MovesList_a_ D movesList{/i X D/toCoord i _index_Coord_c_ D/futureBoard brd sds D/p futureBoard fromCoord bcp D futureBoard i p putinterval futureBoard fromCoord ci(.)putinterval futureBoard player kic not{/score futureBoard _b_Eval_score_ D/move( )D move 0 fromCoord putinterval move 2 toCoord putinterval movesAndScores move score put score highestScore gt{/highestScore score D/highestMove move sds D}if score lowestScore lt{/lowestScore score D/lowestMove move sds D}if}if}F}F movesAndScores highestScore highestMove lowestScore lowestMove e}D/fbm{/useMinMax X D/board X D/player1 X D 5 db/player2 player1 _whiteOrBlack_Invert_s_ D player1 board mae/lowestMove X D/lowestEval X D/highestMove X D/highestEval X D/p1Moves X D/hem 1000000 D/lowestEvalMaximized -1000000 D/highestPlayer1Move null D/lowestPlayer1Move null D useMinMax{p1Moves{/p1MovesEval X D/p1Move X( )cvs D/p1MoveFrom p1Move 0 2 g D/p1MoveTo p1Move 2 2 g D/futureBoard board sds D/p futureBoard p1MoveFrom ci 1 g sds D/p2 p sds D p(P)eq p1MoveTo ci _index_Row_1-8_ 8 eq and{/p2(Q)D}if p(p)eq p1MoveTo ci _index_Row_1-8_ 1 eq and{/p2(q)D}if futureBoard p1MoveTo ci p2 putinterval futureBoard p1MoveFrom ci(.)putinterval player2 futureBoard mae/lowestMove2 X D/lowestEval2 X D/highestMove2 X D/highestEval2 X D/d2 X D highestEval2 hem lt{/hem highestEval2 D/highestPlayer1Move p1Move sds D}if lowestEval2 lowestEvalMaximized gt{/lowestEvalMaximized lowestEval2 D/lowestPlayer1Move p1Move sds D}if}F}{/highestPlayer1Move highestMove D/lowestPlayer1Move lowestMove D}ifelse/bestFrom null D/bestTo null D player1(white)hec{highestPlayer1Move null ne{/bestFrom lowestPlayer1Move 0 2 g D/bestTo lowestPlayer1Move 2 2 g D}if bestTo bestFrom lowestEvalMaximized}{lowestPlayer1Move null ne{/bestFrom highestPlayer1Move 0 2 g D/bestTo highestPlayer1Move 2 2 g D}if bestTo bestFrom hem}ifelse e}D/ugsbcm{5 db/player X D B G player kic{/lastMessage(xxxxx check mate)D/playerTurnMessage(xxxxx win)D lastMessage 0 player putinterval playerTurnMessage 0 player _whiteOrBlack_Invert_s_ putinterval}{/lastMessage(xxxxx cannot move)D/playerTurnMessage(stale mate)D lastMessage 0 player putinterval}ifelse GameState(LAST_MESSAGE)lastMessage put GameState(PLAYER_TURN_MESSAGE)playerTurnMessage put e}D/bamacgs{15 db/gameIsOver false D/highlights 64 array D(black)B G true fbm/bestScore X D/bestFrom X D/bestTo X D bestTo null ne{B G bestFrom bestTo false M/msg X D/highlights X D/canMove X D}{/gameIsOver true D(black)ugsbcm}ifelse(white)B G _player_board_CanPlay_b_ not{/gameIsOver true D(white)ugsbcm}if highlights gameIsOver e}D/SQUARE_SIZE 20 D/PiecesPathsDict<</m{moveto}bind D/l{lineto}bind D/p{newpath SQUARE_SIZE 2 div SQUARE_SIZE 2 div 4 0 360 arc closepath}/r{newpath 5 15 m 7 15 l 7 13 l 9 13 l 9 15 l 11 15 l 11 13 l 13 13 l 13 15 l 15 15 l 15 11 l 13 10 l 13 3 l 7 3 l 7 10 l 5 11 l 5 15 l closepath}/n{newpath 12 15 m 14 3 l 6 3 l 10 9 l 6 9 l closepath}/b{newpath 14 3 m 12 10 l 10 12 3 -30 30 arc 10 12 l 10 12 3 80 210 arc 8 10 l 6 3 l closepath}/q{newpath 4 12 m 8 10 l 10 15 l 12 10 l 16 12 l 12 3 l 8 3 l closepath}/k{newpath 8 3 m 5 9 l 9 9 l 9 11 l 7 11 l 7 13 l 9 13 l 9 15 l 11 15 l 11 13 l 13 13 l 13 11 l 11 11 l 11 9 l 15 9 l 12 3 l closepath}/.{}>>D/_piece_Draw{3 db/x X D/xLowS{x dlc}D PiecesPathsDict xLowS G exec/isWhite{x(.)ne x _piece_IsWhite_b_ and}D gsave isWhite{1.0}{0.0}ifelse setgray fill grestore 0 setgray stroke e}D/_pieces_DrawCapturedPieces{3 db/pieces X D gsave 0 1 pieces length 1 sub{/i X D/c pieces i 1 g D c(.)eq{exit}if c _piece_Draw 12 0 translate i 7 eq{12 -8 mul -15 translate}if}for grestore e }D/ds{10 db/isHatchedSquare X D/p X D/hB X D/hG X D/hR X D isHatchedSquare{0.7}{1.0}ifelse setgray hR null ne hG null ne and hB null ne and{hR hG hB setrgbcolor}if gsave 0 0 SQUARE_SIZE SQUARE_SIZE rectfill 0.0 setgray 0 0 SQUARE_SIZE SQUARE_SIZE rectstroke grestore p _piece_Draw e}D/_highlightIndices_board_DrawBoard{2 2 scale 20 db/b X D/hs X D hs length 64 ne{(-- ERROR: hs length:) print hs length == quit}if gsave gsave 1 setgray -20 -20 400 300 rectfill grestore SQUARE_SIZE 0 mul SQUARE_SIZE 7 mul translate 0 0 moveto 0 1 b length 1 sub{/i X D i 0 ne i 8 mod 0 eq and{SQUARE_SIZE -8 mul SQUARE_SIZE -1 mul translate}if/p{b i 1 g}D/isBlackSquare{i 8 idiv i add 2 mod 0 ne}D/hR null D/hG null D/hB null D hs i G 1 eq{/hR 1 D/hG 1 D/hB 0 D}if hs i G 2 eq{/hR 1 D/hG 0 D/hB 0 D}if hs i G 3 eq{/hR 0 D/hG 1 D/hB 0 D}if hR hG hB p isBlackSquare ds SQUARE_SIZE 0 translate}for grestore gsave 1 1 8{/i X D -13 i 1 sub SQUARE_SIZE mul 6 add moveto i( )cvs show i SQUARE_SIZE mul 14 sub -12 moveto/n( )D n 0 i 96 add put n show}for grestore e}D/_highlights_DrawBoard{5 db/highlights X D gsave 50 50 translate highlights B G _highlightIndices_board_DrawBoard 170 0 translate 0 150 moveto GameState(LAST_MOVE)G show 0 135 moveto B G _b_Eval_score_ 10 string cvs show 0 105 moveto GameState(LAST_MESSAGE)G show 0 90 moveto GameState(PLAYER_TURN_MESSAGE)G show grestore gsave 2 2 scale 185 80 translate 0 0 moveto GameState(CAPTURED_BY_BLACK)G _pieces_DrawCapturedPieces 0 -40 translate GameState(CAPTURED_BY_WHITE)G _pieces_DrawCapturedPieces grestore e}D/Courier findfont 12 scalefont setfont 32 740 moveto NewGame PrintBoardAndGameState gsave 50 50 translate 64 array B G _highlightIndices_board_DrawBoard grestore showpage{/userInput 128 string D(>)print flush(%lineedit)(r)file userInput readline pop token not{()}if{X pop dup length 4 eq{dup/s1 X( )cvs D/s2 X( )cvs D/fromCoord{s1 0 2 g}D/toCoord{s2 2 2 g}D fromCoord _c_IsValidCoordinate_b_ toCoord _c_IsValidCoordinate_b_ and not{(-- BAD COMMAND)== gsave 190 150 moveto(BAD COMMAND)show grestore exit}if B G fromCoord toCoord false M/msg X D/validMoves X D/canMove X D/canMoveCode canMove{1}{2}ifelse D PrintBoardAndGameState exit}if clear(Usage:)=(h2h3 - moves h2 to h3)= exit}loop GameState(CURRENT_PLAYER)G(black)eq{10 db bamacgs/gameIsOver X D/highlights X D PrintBoardAndGameState highlights _highlights_DrawBoard showpage gameIsOver{quit}if e}if}loop