| Chess game | RxChess | A small chess game for RetroForth | Written by Charles Childers and Ray St. Marie. | chess open the vocabulary | play starts the game | new resets the board | e2e4 mv moves a list of 0 or more pieces | **** Now mv does everything **** | This is a version of crc's awesome chess game. | This bashes base to include the natural board coordinate | input language as a subset of the Chess Algebra Notation, | where moves are base 18 numbers or 'characters followed | followed by the 'mv' command. | Soon, the enter key will do all of this. | | teh code include modules\help.data | create a self documenting menu system using help voc: chess chess : play vector ; | play a game | in the war games voice : new vector ; | new board in the first position : mov vector ; | move a piece does en passant automatically : pp vector ; | pawn promote : mvs vector ; | does either mov or pp depending on the stack value : mv vector ; | moves a list of pieces : oo vector ; | kingside castle white or black : ooo vector ; | queenside castle white or black : ds vector ; | depth stack variable ds-on | use 'dsa' to turn on or off the ds | displayed with the board | Turn some RetroForth functions into numbers 13 constant d | this redefines the editor line delete 14 constant e | this redefines the editor on-switch 15 constant f | this redefines the f false 64 constant #sqs | this because of base 18 conversion | extend the numbers to include the | Chess Algebra board co-ords subset | 0 thru H : b-18 18 !base ; b-18 | globals ...basically variable whose-move | 0 white -1 black variable ep-target variable last-move | game logic | depth loc: : sp@ dup [ $f089 2, ] ; reset sp@ 4 / constant base here ] base sp@ 4 / - 1- ; ;loc alias depth ( empty stack || n's -- n's and || count ) | development helper tool :: depth . cr .s ; | depth-stack dip-stick is ds loc: '+ constant sq 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 ; 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! ; | test pawn moves and ep | en passant-ing loc: : offend-sq swap 3 / 3 + swap pos ; | black 4 white 5 :: @last-move unroll-dest offend-sq take-piece ; ;loc is take-pawn 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 48 =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 ; : ooow 1 d 1 a end-castle ; : oob 8 f 8 h end-castle ; : ooob 8 d 8 a end-castle ; : wCastle 2 =if oow ;then ooow ; : bCastle 2 =if oob ;then ooob ; :: dup 'K and 43 =if @last-move unroll swap drop - swap 1 =if wCastle ;then bCastle then ; ;loc is test-king :: test-king test-pawn ; is test-piece | moving :: dup !last-move unroll start-move test-piece end-move ; is mov docstring: mov ." mov ( base18n -- ) makes one peice move" cr ." from source to destination." cr ." For pawns this automatically handles en passant." cr ." example: e2e4 mov" cr ; | promoting :: swap dup mov unroll-dest pos c! ; is pp docstring: pp ." pp ( base18n 'character -- )" cr ." move and promote to 'character" cr ." example: e7d8 'Q pp" cr ." Can also be used to place a piece" cr ." anywhere on the board" cr ." example: e5e5 'Q pp puts a Queen at E5" cr ." note: you must give both source and destination" cr ." even if they are both the same: e2e2 'P pp" cr ; | merge pp and mov making mvs and mv able to promote as well :: dup a1 if whose-move toggle then ; | think this thru **** :: pre-move depth 0; for r 1- pick dup a1