I adapted this program from example I found in a C++ book. It's a really nice example of recursive problem solving.
`*** The Towers of Hanoi Problem ***
`I will use binary system to store rings on poles (1=small ring, 2=medium, 4=large)
DIM Pole(3)
source = 1 : `set start pole
`setup
hide mouse
sync on
DO
`set up new puzzle
repeat : destination= rnd(2)+1 : until destination <> source : `get end pole
repeat : temporary_store= rnd(2)+1 : until temporary_store <> source and temporary_store <> destination
Pole(source) = 7 : Pole(destination) = 0 : Pole(temporary_store) = 0 : `initiate poles
display() : `display the initial puzzle
print "New destination: " ; destination : sync : wait 1000 : `begin puzzle message
source = Transfer(3, source, destination, temporary_store) : `complete the puzzle and return new source
LOOP
`Transfer
FUNCTION Transfer(N, source, destination, temporary_store)
`Problem Fix Variables
S = source
D = destination
T = temporary_store
If N = 1
Move(S, D)
Else
Transfer(N-1, S, T, D)
Move(S, D)
Transfer(N-1, T, D, S)
Endif
ENDFUNCTION destination
`Move
FUNCTION Move(source, destination)
`which ring is to be moved?
Select Pole(source)
Case 1 : ring = 1 : Endcase
Case 2 : ring = 2 : Endcase
Case 3 : ring = 1 : Endcase
Case 4 : ring = 4 : Endcase
Case 5 : ring = 1 : Endcase
Case 6 : ring = 2 : Endcase
Case 7 : ring = 1 : Endcase
Endselect
`Take ring from source and add to destination
Pole(source) = Pole(source) - ring
Pole(destination) = Pole(destination) + ring
`Update display
Display()
ENDFUNCTION
`Display
FUNCTION Display()
cls
For x = 1 to 3
`draw poles
ink rgb(120,40,0),0
Line 100+(100*x), 100, 100+(100*x), 200
`disintegrate pole variables
ink rgb(255,200,0),0
pole = Pole(x) : `store current pole rings value
rings = 0
`big ring?
if pole - 4 >=0
inc rings
box 100+(100*x)-40, 183-((rings-1)*20), 100+(100*x)+40, 200-((rings-1)*20)
pole = pole - 4
endif
`medium ring?
if pole - 2 >=0
inc rings
box 100+(100*x)-30, 183-((rings-1)*20), 100+(100*x)+30, 200-((rings-1)*20)
pole = pole - 2
endif
`small ring?
if pole - 1 >=0
inc rings
box 100+(100*x)-20, 183-((rings-1)*20), 100+(100*x)+20, 200-((rings-1)*20)
pole = pole - 1
endif
Next x
sync
wait 1000
ENDFUNCTION
This code is old so I'll go through it and see if I can make improvements.
[edit]
See below for the improved version:
`*** The Towers of Hanoi Problem ***
set display mode 640,480,16
Hide Mouse
Sync On
randomize timer()
`I will use binary system to store rings on poles (1=small ring, 2=medium, 4=large)
Dim _Pole(3)
source = 2
rem === Main ============================================
Do
`randomize new puzzle
destination = source + 1 + rnd(1)
if destination > 3 then dec destination, 3
temporary_store = 6 - source - destination
`I'll use field 0 to store the ultimate destination. A bit crude but it will do.
_Pole(0) = destination
`initiate ring positions
_Pole(source) = 7 : _Pole(destination) = 0 : _Pole(temporary_store) = 0
display() : `display the initial puzzle state
source = Transfer(3, source, destination, temporary_store) : `complete the puzzle and return new source
Loop
rem === Functions =======================================
`Transfer
Function Transfer(N, source, destination, temporary_store)
`Problem Fix Variables
S = source
D = destination
T = temporary_store
If N = 1
Move(S, D)
Else
Transfer(N-1, S, T, D)
Move(S, D)
Transfer(N-1, T, D, S)
Endif
Endfunction destination
`Move
Function Move(source, destination)
`which ring is to be moved?
Select _Pole(source)
Case 1 : ring = 1 : Endcase
Case 2 : ring = 2 : Endcase
Case 3 : ring = 1 : Endcase
Case 4 : ring = 4 : Endcase
Case 5 : ring = 1 : Endcase
Case 6 : ring = 2 : Endcase
Case 7 : ring = 1 : Endcase
Endselect
`Take ring from source and add to destination
_Pole(source) = _Pole(source) - ring
_Pole(destination) = _Pole(destination) + ring
`Update display
wait key
Display()
Endfunction
`Display
Function Display()
CLS
For x = 1 to 3
`draw poles
ink rgb(120,40,0),0
Line 120+(100*x), 100, 120+(100*x), 200
`disintegrate pole variables
ink rgb(255,200,0),0
pole = _Pole(x) : `store current pole rings value
rings = 0
`big ring?
if pole - 4 >=0
inc rings
box 120+(100*x)-40, 183-((rings-1)*20), 120+(100*x)+40, 200-((rings-1)*20)
pole = pole - 4
endif
`medium ring?
if pole - 2 >=0
inc rings
box 120+(100*x)-30, 183-((rings-1)*20), 120+(100*x)+30, 200-((rings-1)*20)
pole = pole - 2
endif
`small ring?
if pole - 1 >=0
inc rings
box 120+(100*x)-20, 183-((rings-1)*20), 120+(100*x)+20, 200-((rings-1)*20)
pole = pole - 1
endif
`target pole marker?
if _Pole(0) = x then center text 120+(100*x), 60, "TARGET"
Next x
center text 320, 300, "Press ANY key to advance one move."
Sync
Endfunction
I like how I optimised the initialisation of the puzzle: got rid of those nasty repeat loops and only use one call of rnd(); much more efficient.
Shh... you're pretty.