TO CHAIN :SOURCE :TARGET :WORD.LIST ;use :words (the current dictionary) as the third input PR :SOURCE ;if the source word and the target differ only by one the game is over IF ( DIFF :SOURCE :TARGET ) = 1 [PR :TARGET STOP] ;but if not try a word somewhere between the source and target as a new source CHAIN ( SOMEWHERE.BETWEEN :SOURCE :TARGET :WORD.LIST ) :TARGET :WORD.LIST END TO SOMEWHERE.BETWEEN :CURRENT.WORD :TARGET.WORD :WORDS ;see if there is a nearer word to the target than the current word using words LOCAL "BEST MAKE "BEST NEARER.THAN :CURRENT.WORD :TARGET.WORD :WORDS ;if there is, output it ;if not, output some word which differs by one from the current IF NOT EMPTY? :BEST [OP :BEST] [OP ONE.DIFF :CURRENT.WORD :WORDS] END TO NEARER.THAN :W1 :W2 :WORDS ; if you reach the end of the word list then there is no word nearer w2 than w1 IF EMPTY? :WORDS [OP "] ;output the first word of the list if it differs from w1 by one and is nearer w2 IF AND ( 1 = DIFF FIRST :WORDS :W1 ) ( ( DIFF FIRST :WORDS :W2 ) < ( DIFF :W1 :W2 ) ) [OP FIRST :WORDS] ;otherwise try the rest of the list OP NEARER.THAN :W1 :W2 BF :WORDS END TO DIFF :W1 :W2 ;if you have no letters (left) in w1 then the difference is zero ;(this works OK if the words are same length, ;but with e.g. cap and cape it outputs 0) ; IF EMPTY? :W1 [OP 0] ; ;if the first letters of w1 and w2 are the same, ;output the result of comparing the rest of the words ;if not, add 1 to the result of comparing the rest ; (i.e increment the running ;total) ; IF FIRST :W1 = FIRST :W2 [OP DIFF BF :W1 BF :W2] [OP 1 + DIFF BF :W1 BF :W2] END TO ONE.DIFF :WORD :WORDS LOCAL "TRY MAKE "TRY PICKRANDOM :WORDS IF ( DIFF :TRY :WORD ) = 1 [OP :TRY] [OP ONE.DIFF :WORD :WORDS] END TO PICKRANDOM :INPUT OP ITEM 1 + RANDOM COUNT :INPUT :INPUT END MAKE "WORDS [POT CAT CAP CAM BAT BAN CAN CAR CUR CUP PUP PUN PUT BUT BIT BIN TIN TIP BAD BAG BAR BED BEG BET BIB BIG BOG BOW BOY COD COG COT COW COY CUT PAD PAN PAW PAY PEG PEN PET POD PUN TAN TAP TAR TAX TEN TOE TON TOP TOW TOY TUB TUG] ÿ