| RxChess0.0.2 | A small chess game for RetroForth. | Written by Charles Childers and Ray St. Marie. | chess Open the game vocabulary. | play Starts the game. | new Resets the board pieces to first positions. | cb Clears the board to set one up using mv. | mv Moves a list of 0 or more pieces. | oo Castle Kingside. | ooo Castle Queenside. | This is a version of crc's awesome | RetroForth chess game. | The number base is changed to 18 to include | the traditional board coordinate tokens: | Files: A thru H | Ranks: 1 thru 8 | as an input language, being a subset of the | Chess Algebra Notation, | where moves are base 18 numbers... | or base 18 numbers followed by 'chars | ( pronounced tic-characters -- they return the | ASCII value of the character on the stack ) | ...followed by the mv command. | mv handles setting the en passant target square | when pawns move into jeopardy. | Moving a pawn into the ep-target executes en passant. | mv handles en passant pawn taking automatically. | mv recognizes when kings move two squares to mean a castle | to that direction the king is moving in. | The board moves the complimentary rook automatically. | Or use the normal castle commands: | oo (kingside) | ooo (queenside). | Soon, the enter key will do mv. ( 0.0.4 goal i think ) | Other commands are available, be sure to read the help section. | *** RxChess *** voc: chess chess | These vectors expose commands to the console user interface. : play vector ; | "Would you like to play a game?" -- War Games voice : new vector ; | New board in the first position. : cb vector ; | Clear the board to set it up. : mov vector ; | Move a piece. Source*100+dest ( like: e2e4 ) on stack. | Does en passant and castles. : pp vector ; | Pawn promote/piece placement. Source*100+dest or dest | and in both cases a 'char on stack. : mvs vector ; | Does mov or does pp if stack value is a 'char. : mv vector ; | Moves a list of 0 or more pieces on the stack. | Toggles whose-move text displayed. : oo vector ; | Kingside castle white or black. : ooo vector ; | Queenside castle white or black. : ds vector ; | Depth of stack. : dsa vector ; | Turn on the dip-stick. : help-text vector ; | Need a little help? | Turn some RetroForth functions into numbers 13 constant d | redefines the block editor line delete 14 constant e | redefines the block editor on-switch 15 constant f | redefines the false token | convenience constants 64 constant #sqs | this because of base 18 conversion '+ constant sq | value of an empty square | Extend the numbers to include the | Chess Algebra board co-ords subset. | 0 thru H : b-18 18 base ! ; b-18 | globals variable whose-move | 0 white -1 black variable ep-target | sq moving pawn leaped over on first move variable last-move | for handleing two token moves like pawn promote variable ds-on | use 'dsa' to toggle on or off the | depth/stack displayed with the board | in the display code below | depth of stack loc: : sp@ dup [ $f089 2, ] ; reset sp@ 4 / constant base here ] base sp@ 4 / - 1- ; ;loc alias depth | development helper tool :: depth . space space .s ; | depth-stack dip-stick is ds : dsa ds-on toggle ; | dip-stick actuator | Create the local namespace to hide some dictionary words | from the user and to fill those vectors above, creating | the user interface to the board displayed on the screen. loc: | this could have been mechanical but this is prettier. create first-position | A B C D E F G H 'r 1, 'n 1, 'b 1, 'q 1, 'k 1, 'b 1, 'n 1, 'r 1, | 8 'p 1, 'p 1, 'p 1, 'p 1, 'p 1, 'p 1, 'p 1, 'p 1, | 7 sq 1, sq 1, sq 1, sq 1, sq 1, sq 1, sq 1, sq 1, | 6 sq 1, sq 1, sq 1, sq 1, sq 1, sq 1, sq 1, sq 1, | 5 sq 1, sq 1, sq 1, sq 1, sq 1, sq 1, sq 1, sq 1, | 4 sq 1, sq 1, sq 1, sq 1, sq 1, sq 1, sq 1, sq 1, | 3 'P 1, 'P 1, 'P 1, 'P 1, 'P 1, 'P 1, 'P 1, 'P 1, | 2 'R 1, 'N 1, 'B 1, 'Q 1, 'K 1, 'B 1, 'N 1, 'R 1, | 1 | board create board #sqs allot here is new ] first-position board #sqs move reset 0 whose-move ! ; new docstring: new ." new sets the board in the first position" cr ; | functions | game math : abs dup 0 r take-piece pos r> swap c! ; : place for dup r 1- board + c! next drop ; | clear the board for pre-setting pieces using mv :: sq #sqs place ; is cb docstring: cb ." cb clears the board." cr ." use cb to clear the board and" cr ." use mv to set up pieces:" cr ." cb a8 'r b8 'n mv" cr ." this would do like you think" cr ; | test for pawn moves and en passant loc: : offend-sq swap 3 / 3 + swap pos ; :: last-move @ unroll-dest offend-sq take-piece ; ;loc is take-pawn | ep target loc: : correct-for-side swap 4 - 3 * 3 + swap ; : ep-target-set last-move @ unroll-dest correct-for-side 10 * + ep-target ! ; :: last-move @ unroll drop swap drop - abs 2 =if ep-target-set -1 ;then 0 ; ;loc is moving-two? :: dup 'P and 'P =if moving-two? if; last-move @ unroll-dest 10 * + ep-target @ 0 ep-target ! =if take-pawn ;then then ; is test-pawn | test King moves | castles loc: : end-castle start-move end-move ; : oow 1 f 1 h end-castle ; : oob 8 f 8 h end-castle ; : ooow 1 d 1 a end-castle ; : ooob 8 d 8 a end-castle ; : wCastle 2 =if oow ;then ooow ; : bCastle 2 =if oob ;then ooob ; :: dup 'K and 'K =if last-move @ unroll swap drop - dup 0 =if drop drop ;then swap dup 1 =if drop wCastle ;then 8 =if bCastle ;then drop then ; ;loc is test-king :: test-pawn test-king ; is test-piece | moving | filter incomplete moves : dest-only? dup h9 if whose-move toggle then ; | think this thru **** : tic-char? dup a0