' Solve Towers of Hanoi puzzle with picaxe 08m ' Will work with 3 or 4 disks ' Solution adapted from a basic program in the book " Artificial Intelligence Progects For The Commodore 64" ' By Timothy J. O'Malley ' servo on out1 is gripper ' servo on out2 is elevation Y axis ' servo on out4 is rotation ' The next 2 lines set the # of disks and # of moves to solve puzzle ' Comment out the 2 lines you don't need ' 'symbol num = 3 'number of disks 'symbol nummoves = 7 '2 ^ numdisks -1 symbol num = 4 'number of disks symbol nummoves = 15 '2 ^ numdisks -1 symbol closepos = 200 'constants for servo open and close symbol openpos = 130 symbol disksbase = \$50 'start of ram for peek poke commands \$50 - \$7f symbol diskstop = disksbase + 4 'last ram location used to store which stack each disk is on symbol height0= \$55 'ram for towerheight array symbol height1 = height0 + 1 symbol height2 = height0 + 2 'set up variables symbol scratch0 = b0 'bits 7-0 symbol scratch1 = b1 'bits 15-8 symbol scratch2 = b2 symbol scratch3 = b3 symbol Lp = b4 'main loop counter symbol d = b5 'position of rightmost set bit symbol numdisks = b6 symbol servotemp = b7 symbol temp = b8 symbol temp2 = b9 numdisks = num 'set initial state of disks array (all disks on stack 1) for scratch2 = disksbase to diskstop poke scratch2, 1 next scratch2 'initialize height array poke height0,num 'all disk on stack 1 poke height1,0 'stacks 2 and 3 are empty poke height2,0 servo 1,130 ' start gripper servo on 1 open servo 2,130 ' start elevation servo on 2 at highest position servo 4,100 ' start rotation servo on 4 at stack 1 for Lp = 1 to nummoves 'sertxd("Lp = ",#Lp," ") ' get pos of rightmost 1 of move number Lp scratch0 = Lp d = 0 do inc d if bit0 = 1 then exit scratch0 = scratch0 / 2 loop while d <= num ' var d now holds disk number to move scratch1 = disksbase + d peek scratch1,scratch2 scratch3 = scratch2 'scratch2 and scratch3 now hold stack # the disk sets on now 'if number of disks is odd the odd # disks go on stacks in seq of 3-2-1-3-2-1 etc and even # disks 1-2-3-1-2-3 etc 'if number of disks is even the odd # disks go on stacks in seq of 1-2-3-1-2-3 etc and even # disks 3-2-1-3-2-1 etc scratch0 = num 'so we can use bit0 as 1s digit scratch1 = d 'so we can use bit8 as 1s digit if bit0 = 0 and bit8 = 0 then goto down ' even number of disks and even numbered disk to move if bit0 = 0 and bit8 = 1 then goto up ' odd number of disks and even numbered disk to move if bit0 = 1 and bit8 = 0 then goto up ' even number of disks and even numbered disk to move 'fell thru to here so its odd number of disks and odd numbered disk to move so down is direction down: dec scratch2 if scratch2 = 0 then scratch2 =3 endif goto over up: inc scratch2 if scratch2 = 4 then scratch2 =1 endif over: 'scratch2 now holds stack to move disk d to 'print the move disk d from stack #scratch3 to stack #scratch2 'sertxd("d = ",#d," from ",#scratch3," to ",#scratch2,13,10) 'move arm to highest position temp = 6 gosub elevation 'move arm to stack disk will be removed from temp = scratch3 gosub rotate 'move arm to disk height of the stack temp2 = height0 + scratch3 - 1 'get mem loc number of disks or height of tower from array peek temp2,temp 'get actual number of disks gosub elevation dec temp 'stack is now 1 shorter poke temp2,temp 'close gripper gosub closegrip 'move arm to highest position temp = 6 gosub elevation 'move arm to stack to place disk temp = scratch2 gosub rotate 'move arm to top disk height + 1 temp2 = height0 + scratch2 - 1 'get number of disks or height of tower from array peek temp2,temp inc temp gosub elevation poke temp2,temp ' open gripper gosub opengrip 'move arm to highest position temp = 6 gosub elevation 'update array scratch1 = disksbase + d poke scratch1,scratch2 next Lp end 'subroutines rotate: lookup temp,(0,100,144,190),servotemp servopos 4,servotemp pause 1500 return elevation: lookup temp,(0,113,118,122,126,135,135),servotemp ' first number is dummy because we start counting at 0 servopos 2,servotemp pause 1500 return opengrip: servopos 1,openpos pause 1000 return closegrip: servopos 1,closepos pause 1000 return end