Tower of Hanoi in FORTH

The ancient Tower of Hanoi problem is as follows: There are 3 pegs. One peg has on it a stack of rings of reducing size, the smallest on top. The objective is to move the rings one at a time from this peg to a second peg using the third peg as a temporary parking place. The rule is you may never place a ring on top of one which is smaller. This is easily solved with a recursive program. In other words we define a word (HANOI in this example) which calls itself i.e. the word HANOI is part of its own definition.
Because FORTH has no local variables we have to put a copy of all the variables on the stack before calling HANOI and get them back afterwards. Each time HANOI calls itself the stack grows deeper.
Normally if you use a word you are still defining within its definition you will get an UNDEFINED error. To prevent this you have to force FORTH to assume the new word is already part of the dictionary, by using the word RECURSE or SMUDGE according to the dialect. In ROBOFORTH we precede the word with LATEST.

N is the number of rings
SA SB SC are reference numbers for the piles (such as 1,2,3)

VARIABLE SA
VARIABLE SB
VARIABLE SC
VARIABLE N
: HANOI
 SC ! SB ! SA ! N !
 N @ 0= IF EXIT THEN
 N @ SA @ SB @ SC @
 N @ 1 - SA @ SC @ SB @ LATEST HANOI
 SC ! SB ! SA ! N !
 CR ." move a ring from " SA ? ." to " SB ?
 N @ 1 - SC @ SB @ SA @ LATEST HANOI
;
Thus it means if n=0 we've finished, otherwise
move (n-1) plates from a to c
move 1 plate from a to b
move (n-1) plates from c back to b

3 1 2 3 HANOI means move 3 plates from pile 1 to pile 2 (using position 3 as a temporary pile)

It should return with:
move a ring from 1 to 2
move a ring from 1 to 3
move a ring from 2 to 3
move a ring from 1 to 2
move a ring from 3 to 1
move a ring from 3 to 2
move a ring from 1 to 2
Note that there are 7 moves i.e. 2^N-1. For 4 rings the number of moves is 15 etc.

Using the robot in ROBOFORTH

First create 3 ROUTEs representing the 3 pegs each using CARTESIAN ROW with 6 positions. The first 5 positions are for 5 rings and the 6th position is edited to a point above the first peg. This is so the robot can lift a ring clear of a peg before moving to the next. I am assuming that the diameters of the rings are all within the range of the gripper or that each ring has some protrusion or annulus that the robot can grip. Create a route using route, new, cartesian, row, 6 collumns (for 5 rings). Learn the first peg, first (bottom) position first. Then using cartesian relative mode move the robot up on Z by 5 times the thickness of each ring and learn the 6th position. Click interpolate. Then raise the robot some more on Z to clear the top of each peg and edit the 6th line to this position. Copy the route to the next peg using add-to-all to change the X-Y value to suit and repeat for the third peg. In my program these are called pegs 0 1 and 2 because there is an array NR which will contain the number of rings on each peg so the robot knows what height to go to.

In ROBOFORTH the word USER is the same as VARIABLE but creates the variable in a reserved area of memory.

( CARTESIAN ROW ROUTES PEG0 PEG1 PEG2

( PEG NUMBERS
USER SA
USER SB
USER SC
USER N

( NUMBER OF RINGS IN EACH PEG
3 USARRAY NR

: ROUTE?
DUP 0 = IF PEG0 THEN
DUP 1 = IF PEG1 THEN
    2 = IF PEG2 THEN
;

: HANOI
 SC ! SB ! SA ! N !
 N @ 0= IF EXIT THEN
 N @ SA @ SB @ SC @
 N @ 1 - SA @ SC @ SB @ LATEST HANOI
 SC ! SB ! SA ! N !
 13 EMIT ." moving a ring from " SA ? ." to " SB ?
 SB @ NR INC ( INCREMENT TARGET PEG
 SA @ ROUTE? 6 GOTO ( GO TO TOP OF PEG
      SA @ NR @ GOTO ( GO TO CORRECT POSITION ON PEG
      GRIP
      6 GOTO ( BACK TO TOP OF PEG
 SB @ ROUTE? 6 GOTO
      SB @ NR @ GOTO
      UNGRIP
      6 GOTO
 -1 SA @ NR +! ( DECREMENT SOURCE PEG
 N @ 1 - SC @ SB @ SA @ LATEST HANOI
;
: MAIN
CARTESIAN
ALIGN
0 BANK !
CR ." NUMBER OF RINGS " ASK N ! CR
N @ 0 NR ! 0 1 NR ! 0 2 NR !
N @ 0 1 2 HANOI
;
home