' Solve Towers of Hanoi puzzle with picaxe 08m ' Will work with 3 or 8 disks ' Solution adapted from a basic program in the book " Artificial Intelligence Progects For The Commodore 64" ' By Timothy J. O'Malley ' this version outputs to the terminal insead of moving servos ' it will solve the puzzle with 3 to 8 disks ' you can scroll the terminal window up to check the results ' ' 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 num = 5 'symbol nummoves = 31 'symbol num = 7 'symbol nummoves = 127 symbol numminus1 = num - 1 'ram locations for peek and poke commands \$50 - \$7f (decimal 80 - 127) 'this array is 1 byte for each disk symbol disksbase = \$50 '1 dim array used to store which stack each disk is on symbol diskstop = disksbase + 8 'last ram location for up to 8 disks 'this array is 1 byte for each stack , each byte holds that stacks height symbol height0= diskstop + 1 symbol heighttop = height0 + 2 'this is a 2 dimensional array arranged like this example for 4 disks (num = 4) 'each ram position holds the disk # in that location 'a zero indicates it's empty 'ex: if littlest disk (disk 1) is on top position of stack 1 ( 4 high ) then diskarray + 0 = 1 ' if largest disk (disk 4) is on bottom of stack 3 then (diskarray + (3 * num - 1 )) = 4 ' ' stack 1 stack2 stack 3 ' diskarray + 0 diskarray + 4 diskarray + 8 ' diskarray + 1 diskarray + 5 diskarray + 9 ' diskarray + 2 diskarray + 6 diskarray + 10 ' diskarray + 3 diskarray + 7 diskarray + 11 ' symbol diskarray = heighttop + 1 '2 dim array that holds disk data symbol dskarry1 = diskarray + num 'need these symbols defining ram address for bottom of each stack symbol dskarry2 = dskarry1 + num 'they are used by lookup command symbol dskarry3 = dskarry2 + num 'they are 1 greater than actual ram location to save on math later '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 symbol temp3 = b10 numdisks = num 'set initial state of disks array (all disks on stack 1) for scratch2 = disksbase to diskstop poke scratch2, 1 next scratch2 'set initial state of diskarray with all disks on stack 1 for temp = 0 to numminus1 temp2 = temp + 1 scratch2 = diskarray + temp poke scratch2, temp2 next 'initialize height array poke height0,num 'all disk on stack 1 gosub printarray 'print the towers before the any moves for Lp = 1 to nummoves ' 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 to move in variable d, from stack #scratch3, to stack #scratch2 sertxd ("m",#lp," ",#d," ",#scratch3," ",#scratch2,13,10) 'get ram address of of bottom of stack disk will be removed from temp = scratch3 gosub rotate 'servotemp now holds bottom stack ram address + 1 'move arm to disk height of the stack temp2 = height0 + scratch3 - 1 'get ram address of height of tower from height array peek temp2,temp 'get actual number of disks on that stack 'gosub elevation 'update diskarray servotemp = servotemp - temp 'array mem loacation poke servotemp,0 'put a zero in old position dec temp 'stack is now 1 shorter poke temp2,temp 'update stack height 'get ram address of of bottom of stack disk will be moved to temp = scratch2 gosub rotate 'servotemp now holds bottom stack ram address + 1 'move arm to top disk height + 1 temp2 = height0 + scratch2 - 1 'get ram address of height of tower from height array peek temp2,temp inc temp 'stack is now 1 taller poke temp2,temp 'update diskarray servotemp = servotemp - temp 'array mem loacation poke servotemp,d 'put a disk number in position 'update array scratch1 = disksbase + d poke scratch1,scratch2 ' print stacks gosub printarray next Lp end 'subroutines rotate: lookup temp,(0,dskarry1,dskarry2,dskarry3),servotemp 'bottom positions of diskarry with 1 added to each stack so index is right return printarray: for temp2 = 0 TO numminus1 for temp3 = 0 TO 2 scratch1 = temp3 * num scratch1 = scratch1 + temp2 + diskarray peek scratch1,temp sertxd(#temp) sertxd(" ") next sertxd(13,10) next sertxd(13,10) return