@prog can't-stop.muf 1 9999 d 1 i ( All properties are stored on trigger @ location. _csprop-n number of players playing [0 through 4] _csprop-w width of a display column [4 for 1 through 3 players, 5 for 4] _csprop-winner which player has won, 0 or absent if none _csprop-p-N dbref of player #N [N from 1 through 4] _csprop-closed true if no more players may join, absent if not _csprop-turn player whose turn it is, 1 through 4 0 or missing before begin or after game end _csprop-claim-N if column N still open, 0 or absent if column N claimed, number of player who claimed it _csprop-at-N-M position of player N's permanent marker on column M 0 or absent for none, 1 for first space, etc when a column is claimed, markers disappear _csprop-tmp-col-N column on which temporary marker N is, 0 or absent if not yet placed _csprop-tmp-at-N position of temporary marker N, 0 or absent if not yet placed _csprop-dice what the dice show [4-char string], absent if not rolled ) : obj trigger @ location ; : cs-prefix "* " ; : cs-n "_csprop-n" ; : cs-w "_csprop-w" ; : cs-winner "_csprop-winner" ; : cs-turn "_csprop-turn" ; : cs-dice "_csprop-dice" ; : cs-closed "_csprop-closed" ; : cs-p "_csprop-p-" swap intostr strcat ; : cs-claim "_csprop-claim-" swap intostr strcat ; : cs-tcol "_csprop-tmp-col-" swap intostr strcat ; : cs-tat "_csprop-tmp-at-" swap intostr strcat ; : cs-at "_csprop-at" rot intostr rot intostr 3 "-" rimplode ; : set-or-remove dup if 0 addprop else pop remove_prop then ; : i-set-or-remove dup if intostr 0 addprop else pop remove_prop then ; : p@ obj swap getpropstr ; : p! obj swap rot set-or-remove ; : pi@ obj swap getpropstr atoi ; : pi! obj swap rot i-set-or-remove ; : p++ dup pi@ 1 + swap pi! ; : say me @ swap notify ; : sayhere loc @ swap #-1 swap notify_except ; : pfxsay cs-prefix swap strcat say ; : pfxsayhere cs-prefix swap strcat sayhere ; : p-name cs-p pi@ dbref name ; : pturn-name cs-turn pi@ p-name ; : p-letter "?abcd" swap 1 substr ; : col-height 7 - abs -2 * 12 + ; : strpow (s n -- s) dup not if pop pop "" exit then dup 1 = if pop exit then dup 1 & if over swap 2 / strpow dup 3 "" rimplode else 2 / strpow dup strcat then ; : replace-at-x (str x ch -- str') -rot strcut swap -1 strcut pop -rot 3 "" rimplode ; : dicestr ( -- s) cs-dice p@ 1 rexplode " " rimplode "<" swap ">" 3 "" rimplode ; : clear-temp-markers 1 3 1 for 0 over cs-tcol pi! 0 swap cs-tat pi! loop ; : clear-dice "" cs-dice p! ; : set-new-turn cs-turn pi! clear-temp-markers clear-dice ; : announce-turn loc @ "It is " pturn-name "'s turn." 3 "" rimplode pfxsayhere ; : setarrstr (arr x y str -- ) over 5 pick aget (a x y sub old) 4 pick over strlen - dup 0 > if (a x y sub old x-ol) " " swap strpow strcat else pop then (a x y sub old) 4 rotate strcut 3 pick strlen strcut swap pop rot swap 3 "" rimplode swap rot aset ; : choosetopchar (c -- s) cs-claim pi@ dup if p-letter else pop "_" then ; : choosecolchar (c -- s) cs-claim pi@ if "." else " " then ; : charbarstr (s -- s') cs-w pi@ 1 - strpow "|" swap over 3 "" rimplode ; : choosetopstr (c -- s) choosetopchar charbarstr ; : choosecolstr (c -- s) choosecolchar charbarstr ; : set-random-dice 1 4 1 for pop random 6 % 1 + intostr loop 4 "" rimplode cs-dice p! ; : merge (x1 ... xN y1 ... yM N M fn -- z1 ... zN+M N+M) over 4 pick + -4 rotate begin over 4 pick and while over 4 pick + 4 + pick 3 pick 5 + pick 3 pick exec if rot 1 - -3 rotate else over 4 + rotate 4 pick 4 pick + 4 + -1 * rotate swap 1 - swap then loop 3 mpop ; : sort (x1 ... xN N fn -- x1 ... xN N) (fn is x1 x2 -- i and returns true if the things are correctly ordered.) over 2 < if pop exit then over 2 / rot over - over 3 + -1 * rotate over over 3 + -1 * rotate swap sort dup 2 + pick over 4 + pick 3 pick + 4 + 3 pick 2 + roll sort dup 3 + rotate swap dup 3 + rotate merge ; : dice-numbers cs-dice p@ 1 explode pop 1 4 1 for pop 4 rotate atoi loop ; : compute-sum-pairs dice-numbers (a b c d) 4 copy dup -rot + -rot + 4 2 roll + 6 3 roll (c+d b+d d+a a b c) 3 copy + -5 rotate + -5 rotate + -5 rotate (c+d a+b b+d c+a d+a b+c) ; : compute-possible-sums compute-sum-pairs 6 { > } sort dup 2 -1 for (sN ... s1 N i) dup 2 + dup pick swap 1 + pick = if rotate pop 1 - else pop then loop ; : my-turn-check ( -- bool) cs-closed p@ if cs-turn pi@ dup if cs-p pi@ dbref me @ dbcmp if 0 else "It's not your turn." pfxsay 1 then else pop "The game is already over." pfxsay 1 then else "The game is not yet started." pfxsay 1 then ; : tmarker-for-col (c -- tx) (given a column marker, returns index of temp marker in that column, 1 thorugh 3, or 0 if none.) 1 3 1 for dup cs-tcol pi@ 3 pick = if swap pop exit then pop loop pop 0 ; : col-playable? (n -- bool) dup cs-claim pi@ if pop 0 exit then dup tmarker-for-col dup if cs-tat pi@ swap col-height <= else pop pop 1 then ; : busted-free? (We've got a free temporary marker, so any playable column among the dice sums means we haven't gone bust.) begin dup 0 > while 1 - swap col-playable? if mpop 0 exit then loop not ; : busted-busy? (All temporary markers have been placed. To avoid going bust, we have to have a dice sum in a column with a temp marker, and it must also be a playable column.) begin dup 0 > while 1 - swap dup tmarker-for-col dup if cs-tat pi@ swap col-height <= if mpop 0 exit then else pop pop then loop not ; : busted? ( -- bool) compute-possible-sums 3 cs-tcol pi@ if busted-busy? else busted-free? then ; : pass-turn cs-turn pi@ cs-n pi@ % 1 + set-new-turn announce-turn ; : claim-column (c -- ) cs-turn pi@ over cs-claim pi! 1 cs-n pi@ 1 for over cs-at 0 swap pi! loop ; : drop-falses (xN ... x1 N -- xM ... x1 M) dup 1 -1 for dup 2 + rotate dup if swap 1 + neg rotate else pop pop 1 - then loop ; : find-free-tmarker 1 3 1 for dup cs-tcol pi@ not if exit then pop loop 0 ; : move1 (col -- ) compute-sum-pairs 0 1 6 1 for pop 1 rot << | loop over >> 1 & not if pop "The dice don't show that." pfxsay exit then dup col-playable? not if pop "That column is not playable." pfxsay exit then 3 cs-tcol pi@ if dup tmarker-for-col not if pop "You have no temporary marker available." pfxsay exit then then dice-numbers + + + over - (col other) dup col-playable? if (It's okay if: [a] no temp markers free, col has temp marker, other doesn't; [b] col!=other, only one temp marker free, neither has temp marker; [c] col=other and only one space left, with or without a temp marker being there.) { (test condition [c], least likely / cheapest outer if) 2 copy = if dup tmarker-for-col dup if cs-tat else pop cs-turn pi@ over cs-at then pi@ over col-height = if 0 exit then then (test condition [a]) 3 cs-tcol pi@ if dup tmarker-for-col not if 0 exit then then (test condition [b] - note that we aren't here if col has no temp marker and no markers free) 2 copy != if 2 cs-tcol pi@ if over tmarker-for-col not if dup tmarker-for-col not if 0 exit then then then then 1 } exec if = if "You must play twice if you play there." else "You must play the other column as well if you do that." then pfxsay exit then then pop (col) dup tmarker-for-col dup if cs-tat dup pi@ else pop find-free-tmarker dup cs-tcol 3 pick swap pi! cs-tat cs-turn pi@ 3 pick cs-at pi@ then 1 + swap pi! pturn-name " moves in column " rot intostr "." 4 "" rimplode pfxsayhere clear-dice ; : 2to1 (a b -- c) 2 copy > if swap then 4 << + ; : 1to2 (c -- a b) dup 15 & swap 4 >> ; : move2 (col1 col2 -- ) 2to1 compute-sum-pairs 2to1 -rot 2to1 4 2 roll 2to1 4 copy 4 pick != swap 4 pick != and -rot != and if 4 mpop "The dice don't show that." pfxsay exit then 3 mpop 1to2 2 copy = if cs-claim pi@ if pop "That column is not playable." pfxsay exit then dup tmarker-for-col dup if (col tmx) 2 copy cs-tat dup pi@ 1 + rot col-height over < if 4 mpop "You're only one move from the top of that column." pfxsay exit then 1 + swap pi! else pop find-free-tmarker dup if cs-turn pi@ 3 pick cs-at pi@ 1 + dup 4 pick col-height > if 3 mpop "You're only one move from the top of that column." pfxsay exit then 1 + over cs-tat pi! 2 copy cs-tcol pi! else pop pop "You have no temporary marker available." pfxsay exit then then pop pturn-name " moves twice in column " rot intostr "." 4 "" rimplode pfxsayhere clear-dice exit then over col-playable? over col-playable? and not if pop pop "One or both of those columns is not playable." pfxsay exit then dup tmarker-for-col dup if dup cs-tat pi@ 4 pick tmarker-for-col dup if dup cs-tat pi@ else pop find-free-tmarker dup if 5 pick over cs-tcol pi! cs-turn pi@ 6 pick cs-at pi@ else 5 mpop "You have no temporary marker available." pfxsay exit then then else pop over tmarker-for-col dup if find-free-tmarker dup if 3 pick over cs-tcol pi! cs-turn pi@ 4 pick cs-at pi@ rot dup cs-tat pi@ else 4 mpop "You have no temporary marker available." pfxsay exit then else pop 2 cs-tcol pi@ if pop pop "You don't have two temporary markers available." pfxsay exit then 1 cs-tcol pi@ if 3 2 else 2 1 then 3 copy pop cs-tcol pi! 4 pick over cs-tcol pi! cs-turn pi@ dup 5 pick cs-at pi@ swap 6 pick cs-at pi@ rot swap then then (col1 col2 col2tm col2at col1tm col1at) 1 + swap cs-tat pi! 1 + swap cs-tat pi! "." swap intostr rot intostr " and " swap " moves in columns " pturn-name 6 "" implode pfxsayhere clear-dice ; : setarr-setup (w arr pno col at -- w arr pno col arr x y) over 2 - 6 pick * 4 pick cs-n pi@ dup 1 = if pop pop 2 else 2 = eif 2 * 1 - then + 5 pick swap rot 1 - ; : check-win ( -- bool) 0 2 12 1 for cs-claim pi@ 4 * 1 swap << + loop 1 cs-n pi@ 1 for swap 4 >> dup 15 & 3 >= if pop dup cs-winner pi! p-name " wins!" strcat pfxsayhere 0 cs-turn pi! 1 exit then swap pop loop pop 0 ; : doreset swap "" strcmp if "Usage: " swap strcat pfxsay exit then pop 0 cs-n pi! 1 4 1 for 0 over cs-p pi! loop "" cs-closed p! 0 cs-turn pi! 2 12 1 for 1 4 1 for over cs-at 0 swap pi! loop 0 swap cs-claim pi! loop clear-temp-markers clear-dice 0 cs-w pi! 0 cs-winner pi! "Game reset by " me @ name strcat "." strcat pfxsayhere ; : dojoin swap "" strcmp if "Usage: " swap strcat pfxsay exit then pop cs-n pi@ 0 > if 1 cs-n pi@ 1 for cs-p pi@ dbref me @ dbcmp if "You are already playing!" pfxsay exit then loop then cs-closed p@ if "The game has already begun!" pfxsay exit then cs-n pi@ 3 > if "Maximum number of players reached, sorry." pfxsay exit then cs-n p++ cs-n pi@ cs-p me @ int swap pi! me @ name " has joined the game." strcat pfxsayhere ; : dobegin swap "" strcmp if "Usage: " swap strcat pfxsay exit then pop 1 cs-n pi@ 0 > if 1 cs-n pi@ 1 for cs-p pi@ dbref me @ dbcmp if pop 0 then loop then if "You are not playing!" pfxsay exit then cs-closed p@ if "The game has already begun!" pfxsay exit then cs-n pi@ 1 < if "How did this happen? No players but we're here?!" pfxsay "Please don't touch this Can't Stop set, and report this to Mouse." pfxsay exit then "Game begun by " me @ name strcat "." strcat pfxsayhere "y" cs-closed p! cs-n pi@ 3 > if 5 else 4 then cs-w pi! random cs-n pi@ % 1 + set-new-turn announce-turn ; : dostatus swap "" strcmp if "Usage: " swap strcat pfxsay exit then pop cs-closed p@ not if cs-n pi@ 4 < if "Game is open to more players." pfxsay "Players joined so far:" else "Game has not yet begun." pfxsay "Players joined:" then cs-n pi@ dup if swap " " 1 4 rotate 1 for p-name strcat strcat ", " loop pop "." strcat else pop pop "No players have joined yet." then pfxsay exit then cs-turn pi@ if "Game has begun." else "Game has ended; " cs-winner pi@ p-name " won." 3 "" rimplode then pfxsay "Players:" " " 1 cs-n pi@ 1 for p-name strcat strcat ", " loop pop "." strcat pfxsay cs-turn pi@ if "It is " pturn-name strcat "'s turn." strcat pfxsay pturn-name cs-dice p@ if " has rolled " dicestr "." 4 "" rimplode else 1 cs-tcol pi@ eif " must roll or stop." strcat else " must roll." strcat then pfxsay then ; : doboard swap "" strcmp if "Usage: " swap strcat pfxsay exit then pop cs-closed p@ not if "No game is in progress." pfxsay exit then "" 1 cs-n pi@ 1 for " " swap dup p-letter "=" rot p-name 5 "" rimplode loop 2 -2 substr pfxsay cs-w pi@ 13 1 newarray "" -1 -1 4 pick afill (colwidth array) 2 12 1 for (w arr c) dup col-height over 2 - 5 pick * (w arr c h x0) 4 pick over 4 pick 6 pick choosetopstr setarrstr swap 1 - 0 -1 for 4 pick 3 pick rot 5 pick choosecolstr setarrstr loop pop pop loop (w arr) 1 cs-n pi@ 1 for 2 12 1 for 2 copy cs-at pi@ dup if (w arr pno cno pos) setarr-setup 5 pick p-letter setarrstr else pop then (w arr pno cno) pop loop pop loop (w arr) 1 3 1 for (w arr tmx) dup cs-tcol pi@ dup if (w arr tmx col) swap cs-tat pi@ cs-turn pi@ -rot (w arr pno col at) setarr-setup "*" setarrstr then pop pop (w arr) loop (w arr) 12 0 -1 for over aget pfxsay loop pop (w) "" 2 12 1 for (w s n) " " swap intostr strcat 3 pick neg dup neg substr strcat loop 1 -1 substr pfxsay pop cs-turn pi@ dup if p-name "'s turn; dice " cs-dice p@ if "show " dicestr "." 3 "" rimplode else "have not been rolled." then 3 "" rimplode else pop "Game is over. " cs-winner pi@ p-name " won." 3 "" rimplode then pfxsay ; : doroll swap "" strcmp if "Usage: " swap strcat pfxsay exit then pop my-turn-check if exit then cs-dice p@ if "You've already rolled!" pfxsay exit then set-random-dice pturn-name " rolls the dice and gets " dicestr "." 4 "" rimplode pfxsayhere busted? if pturn-name " goes bust." strcat pfxsayhere pass-turn exit then ; : domove swap " " explode drop-falses dup 1 != over 2 != and if mpop "Usage: " over " col" 3 "" rimplode pfxsay " " swap " col1 col2" 3 "" rimplode pfxsay exit then cs-dice p@ not if 1 + mpop "You must roll first!" pfxsay exit then 1 = if swap pop atoi move1 else rot pop atoi swap atoi move2 then depth if 999 "domove stuff on stack" pstack then ; : dostop swap "" strcmp if "Usage: " swap strcat pfxsay exit then pop my-turn-check if exit then cs-dice p@ if "You've already rolled - it's too late to change your mind now!" pfxsay exit then 1 cs-tcol pi@ dup if "." swap 2 cs-tcol pi@ dup if 3 cs-tcol pi@ dup if intostr -rot intostr -rot intostr "columns " ", " -rot ", and " -5 rotate 9 else pop intostr swap intostr "columns " " and " -rot 7 then else pop intostr "column " 5 then " stops rolling, advancing in " pturn-name rot "" implode else pturn-name " foregoes rolling altogether." strcat then pfxsayhere 1 3 1 for dup cs-tcol pi@ dup if swap cs-tat pi@ over col-height over < if pturn-name " claims column " 4 pick intostr "." 4 "" rimplode pfxsayhere pop claim-column else cs-turn pi@ rot cs-at pi! then else pop pop then loop check-win if clear-temp-markers clear-dice else pass-turn then ; : dorules pop dup "" strcmp not if pop "+--------------------------------------------+" pfxsay "| Can't Stop Mouse's MUF version |" pfxsay "+--------+-----------------------------------+" pfxsay "| rules | Print rules |" pfxsay "| reset | Reset the game |" pfxsay "| join | Join in a game |" pfxsay "| begin | Begin a game |" pfxsay "| status | Show the game status |" pfxsay "| board | Show the game board |" pfxsay "| roll | Roll the dice |" pfxsay "| move | Move markers |" pfxsay "| stop | End your turn |" pfxsay "+--------+-----------------------------------+" pfxsay "| rules gives help for . |" pfxsay "| rules how gives a how-to-play summary.|" pfxsay "| rules example gives an example. |" pfxsay "+--------------------------------------------+" pfxsay exit then dup "rules" strcmp not if pop "rules - show rules and command info." pfxsay "By itself, gives a list of commands; with a command name, gives help" pfxsay "on that command." pfxsay exit then dup "reset" strcmp not if pop "reset - reset the game." pfxsay "This resets the game completely. Everything starts over; players" pfxsay "must join and the game must be begun again." pfxsay exit then dup "join" strcmp not if pop "join - join the game." pfxsay "Adds you to the list of people playing the game." pfxsay "Works only before the game has begun." pfxsay "At most four players can play." pfxsay exit then dup "begin" strcmp not if pop "begin - begin a game." pfxsay "Begins a game. When one of the players issues this command, no" pfxsay "further join commands are permitted, a player is chosen randomly" pfxsay "to play first, and play starts." pfxsay exit then dup "status" strcmp not if pop "status - show game status." pfxsay "Describes everything about the game's status except details of where." pfxsay "markers are on the baord; use `board' for that." pfxsay exit then dup "board" strcmp not if pop "board - show game board." pfxsay "Shows the game board, indicating where players' markers are." pfxsay exit then dup "roll" strcmp not if pop "roll - roll the dice." pfxsay "Rolls the dice. Once you do this, you must use the `move' command" pfxsay "to move at least one marker; if you can't move, you go bust for that turn." pfxsay "As long as you don't win the game and you don't go bust, you can keep" pfxsay "rolling as long as you dare." exit then dup "move" strcmp not if pop "move - move your marker(s)." pfxsay "When you have rolled the dice, if you don't go bust, you must move" pfxsay "one or two of your markers. Give the numbers of the columns you wish" pfxsay "to move in, as in `move 6 10'; if you want to move in only one column," pfxsay "give only one number. To move twice in the same column, give that" pfxsay "column number twice." pfxsay exit then dup "stop" strcmp not if pop "stop - end your turn." pfxsay "If you haven't gone bust, but you don't want to risk rolling again," pfxsay "give the `stop' command instead of the `roll' command. This makes" pfxsay "permanent any gains you have made and passes the turn to the next player." pfxsay exit then dup "how" strcmp not if pop "Can't Stop is a game of luck and daring." pfxsay "The board has eleven columns, numbered from 2 through 12, the eleven" pfxsay "totals possible with two dice; each column has some number of spaces" pfxsay "that markers advance along. The first person to get a marker to" pfxsay "the top of a column claims that column; nobody else can use it then." pfxsay "The first person to claim three columns wins the game." pfxsay "There are three `temporary' markers, which are used by the player" pfxsay "whose turn it is. When it's your turn, you roll four dice; you" pfxsay "then divide them into two pairs, and move temporary markers up the" pfxsay "columns corresponding to the sums of those pairs. The temporary" pfxsay "marker starts from your (permanent) marker in that column, or the bottom" pfxsay "of the column if you have no marker on it. You can't move in a column" pfxsay "anyone has already claimed, or one which has a temporary marker already" pfxsay "at the top. Also, if all three temporary markers are in play, you can't" pfxsay "move in a column where you don't have one. If you roll numbers that mean" pfxsay "you can't move at all, you go bust, the temporary markers are removed," pfxsay "and your turn ends. But if you have made some gains and don't want to" pfxsay "risk them, you can choose to end your turn instead of rolling the dice," pfxsay "in which case your permanent markers are advanced to where the temporary" pfxsay "markers are, possibly claiming one or more rows and maybe even winning!" pfxsay "If you move in one column, then you must, if you can, move in the column" pfxsay "corresponding to the other dice sum. You are, however, allowed to pick" pfxsay "a column to move in that means you can't use the other sum, even if by" pfxsay "choosing differently you could use both sums." pfxsay exit then dup "example" strcmp not if pop "example - example of use of commands." pfxsay "This is a short example showing the use of the commands." pfxsay "It describes the beginning of a game among three players, Herman," pfxsay "Airon, and Twibbit." pfxsay "" pfxsay "Player Command Everyone sees" pfxsay "Herman reset * Game reset by Herman." pfxsay "Herman join * Herman has joined the game." pfxsay "Twibbit join * Twibbit has joined the game." pfxsay "Airon join * Airon has joined the game." pfxsay "Twibbit begin * Game begun by Twibbit." pfxsay " * It is Airon's turn." pfxsay "Airon roll * Airon rolls the dice and gets <4 4 2 4>." pfxsay "Airon move 6 8 * Airon moves in columns 6 and 8." pfxsay "Airon roll * Airon rolls the dice and gets <4 1 1 5>." pfxsay "Airon move 5 6 * Airon moves in columns 5 and 6." pfxsay "Airon roll * Airon rolls the dice and gets <1 4 5 5>." pfxsay "Airon move 5 * Airon moves in column 5." pfxsay " Airon couldn't move in column 9 or 10 because all three" pfxsay " temporary markers were already in play. She could have" pfxsay " chosen to move in column 6 instead of 5." pfxsay "Airon stop * Airon stops rolling, advancing in columns 5, 6, and 8." pfxsay " * It is Herman's turn." pfxsay "Herman roll * Herman rolls the dice and gets <1 1 4 6>." pfxsay "Herman move 2 10 * Herman moves in columns 2 and 10." pfxsay "Herman roll * Herman rolls the dice and gets <5 6 5 6>." pfxsay "Herman move 11 11 * Herman moves twice in column 11." pfxsay "Herman roll * Herman rolls the dice and gets <5 4 4 6>." pfxsay "Herman move 11 * Herman moves in column 11." pfxsay " Herman could have moved in column 8 instead. He could also have" pfxsay " moved in 9 and 10, but not 9 without 10 or 10 without 9." pfxsay "Herman roll * Herman rolls the dice and gets <1 6 6 6>." pfxsay " * Herman goes bust." pfxsay " * It is Twibbit's turn." pfxsay " Herman went bust because with <1 6 6 6>, 7 and 12 are the only" pfxsay " possible sums. All three temporary markers are in play, none of" pfxsay " them on either of those columns. He lost all his gains in columns" pfxsay " 2, 10, and 11." pfxsay exit then "Don't have any rules entry for `" swap "'." strcat strcat pfxsay ; : main trigger @ "_action" getpropstr dup not if pop trigger @ name then dup "nextword" strcmp not if pop begin dup " " 1 strncmp not while 1 -1 substr loop dup " " instr dup if strcut swap 0 -1 substr else pop "" swap then dup not if pop "Use `" command @ " rules' for help." 3 "" rimplode say exit then then dup "rules" strcmp not if dorules exit then dup "reset" strcmp not if doreset exit then dup "join" strcmp not if dojoin exit then dup "begin" strcmp not if dobegin exit then dup "status" strcmp not if dostatus exit then dup "board" strcmp not if doboard exit then dup "roll" strcmp not if doroll exit then dup "move" strcmp not if domove exit then dup "stop" strcmp not if dostop exit then "Unrecognized command `" swap strcat "'." strcat pfxsay ; . c q