Author Topic: Re: the TOWERS OF HANOI  (Read 1937 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: the TOWERS OF HANOI
« Reply #15 on: March 03, 2019, 02:19:23 pm »
Hi TempodiBasic,

Looking at your code:
Code: QB64: [Select]
  1. SUB MakeMoves (NumMoves&)

Are you moving disks a tower section at a time? I haven't figured out how to watch your code move by move. (It's so different from what I am working.) Append: never mind I figured it out.

Also from the you tube link I posted above, I made a non-recursive Towers of Hanoi solver that runs slightly slower than the recursive one from Samples. Actually I made two, by optimizing the first nonRecursive, nonRecursive1 looks quite different!

Code: QB64: [Select]
  1. _TITLE "Towers of Hanoi 4 non recurs" 'B+ started 2019-03-03
  2.  
  3. 'OK the samples game had a better ways 1. tracks the top disk in each tower and had a disk move routine
  4. 'it also called the first tower 0 in the tower array
  5.  
  6. '2019-03-02 Towers of Hanoi 2 modified with move count and no updates in Auto Mode until finished.
  7. '2019-03-02  Towers of Hanoi 3 add working non-recursive method that is slower than recursive.
  8.  
  9. '2019-03-03 Towers of Hanoi 4 non recurs, Attempt to improve nonRecursive speed in nonRecursive1.
  10. ' Yes it works and is faster than
  11. 'the other non-recursive BUT still not as fast as AUTO which isn't as fast as Tempodi's recursive.
  12.  
  13. CONST xmax = 800
  14. CONST ymax = 600
  15. SCREEN _NEWIMAGE(xmax, ymax, 32)
  16. _SCREENMOVE 300, 20
  17. DIM SHARED nDisks AS INTEGER, hDisk AS INTEGER, wMult AS INTEGER
  18.  
  19. nDisks = 10 '<<<<<<<<<<<<   modify as needed max tested 25 worked
  20.  
  21. 'top tracks the amount of disks in each tower, dpal assigns a color to each disk, tower stores the 3 sets of disk values
  22. DIM SHARED nT(2) '<<<  so much smarter than my first attempt that used 2 functions on tower array
  23. DIM SHARED dpal(1 TO nDisks) AS _UNSIGNED LONG
  24. DIM SHARED tower(0 TO 2, 1 TO nDisks) AS INTEGER
  25.  
  26. 'init
  27. hDisk = 520 / nDisks 'for drawing disk heights
  28. wMult = 240 / nDisks 'multiplier for disk widths
  29. FOR i = 1 TO nDisks
  30.     dpal(i) = _RGB32(RND * 255, RND * 255, RND * 255)
  31. FOR i = 1 TO nDisks
  32.     tower(0, i) = nDisks + 1 - i
  33. nT(0) = nDisks
  34. updateScreen
  35. INPUT "Enter p to Play Game or Enter, n to solve non recursively, s to solve recursively: "; choice$
  36. IF choice$ = "p" THEN
  37.     playGame
  38. ELSEIF choice$ = "n" THEN
  39.     nonRecursive1
  40.     AUTO
  41.  
  42. SUB playGame
  43.     WHILE _KEYDOWN(27) = 0
  44.         'message click or press for fromt
  45.         fromT = 0: toT = 0
  46.         rowMessage 1, "Click or press tower # of disk to move... "
  47.         rowMessage 2, " "
  48.         fromT = getTower%
  49.         rowMessage 1, "Moving disk from tower" + STR$(fromT + 1)
  50.         IF nT(fromT) THEN
  51.             rowMessage 2, "Click or press tower # to move disk to..."
  52.             toT = getTower
  53.             rowMessage 2, "Moving disk to tower" + STR$(toT + 1)
  54.             IF toT <> fromT THEN
  55.                 IF nT(toT) = 0 THEN
  56.                     moveDisk fromT, toT
  57.                     updateScreen
  58.                 ELSEIF tower(fromT, nT(fromT)) < tower(toT, nT(toT)) THEN
  59.                     moveDisk fromT, toT
  60.                     updateScreen
  61.                 ELSE
  62.                     rowMessage 3, "Can't place a larger disk on top a smaller one."
  63.                 END IF
  64.             ELSE
  65.                 rowMessage 3, "You attempted to move a disk to the same tower."
  66.             END IF
  67.         ELSE
  68.             rowMessage 3, "There is no disk to move in tower" + STR$(fromT + 1)
  69.         END IF
  70.         fromT = 0: toT = 0
  71.         _LIMIT 30
  72.     WEND
  73.  
  74. SUB getClick (mx, my, q)
  75.     WHILE _MOUSEINPUT: WEND '<<<<<<<<<<  clear previous mouse activity   ITS NOT CLEARING!!!!!!!!!!!!!!
  76.     _KEYCLEAR 'clear previous key presses
  77.     mx = -1: my = -1: q = 0
  78.     DO WHILE mx = -1 AND my = -1
  79.         q = _KEYHIT
  80.         IF q = 27 OR (q > 31 AND q < 126) THEN _KEYCLEAR: EXIT SUB
  81.         i = _MOUSEINPUT: mb = _MOUSEBUTTON(1)
  82.         DO WHILE mb 'wait for release
  83.             q = _KEYHIT
  84.             IF q = 27 OR (q > 31 AND q < 126) THEN EXIT SUB
  85.             i = _MOUSEINPUT: mb = _MOUSEBUTTON(1): mx = _MOUSEX: my = _MOUSEY
  86.             _LIMIT 1000
  87.         LOOP
  88.         _LIMIT 1000
  89.     LOOP
  90.  
  91. SUB updateScreen
  92.     CLS
  93.     LINE (0, 580)-STEP(xmax, 0)
  94.     FOR t = 0 TO 2
  95.         FOR i = 1 TO nDisks
  96.             IF tower(t, i) THEN
  97.                 xhalf = ((tower(t, i)) * wMult) / 2
  98.                 LINE ((t + 1) * 250 - xhalf - 125, 580 - hDisk * i)-STEP(2 * xhalf, hDisk), dpal(tower(t, i)), BF
  99.             END IF
  100.         NEXT
  101.     NEXT
  102.     _PRINTSTRING (0, ymax - 18), SPACE$(11) + "Tower #1" + SPACE$(24) + "Tower #2" + SPACE$(23) + "Tower #3"
  103.     _PRINTSTRING (300, 60), STR$(nMoves) + " Moves"
  104.     'INPUT "OK press enter.."; wate$
  105.     _DISPLAY
  106.  
  107. FUNCTION getTower% ()
  108.     getClick mx, my, q
  109.     IF ABS(150 - mx) < 125 THEN t = 0
  110.     IF ABS(400 - mx) < 125 THEN t = 1
  111.     IF ABS(650 - mx) < 125 THEN t = 2
  112.     IF q THEN
  113.         IF INSTR("123", CHR$(q)) > 0 THEN t = INSTR("123", CHR$(q)) - 1
  114.         IF CHR$(q) = "q" OR q = 27 THEN END
  115.     END IF
  116.     getTower% = t
  117.  
  118. 'clear row with spaces then print message$ on it
  119. SUB rowMessage (lineNumber, message$)
  120.     LOCATE lineNumber, 1: PRINT SPACE$(xmax \ 8)
  121.     LOCATE lineNumber, 1: PRINT message$
  122.     _DISPLAY
  123.  
  124. 'from sample (my attempt was way more complicated)
  125. SUB moveDisk (fromT, toT)
  126.     tower(toT, nT(toT) + 1) = tower(fromT, nT(fromT))
  127.     nT(toT) = nT(toT) + 1
  128.     tower(fromT, nT(fromT)) = 0
  129.     nT(fromT) = nT(fromT) - 1
  130.     nMoves = nMoves + 1
  131.     IF nDisks < 10 THEN updateScreen
  132.  
  133. 'from sample
  134. SUB AUTO
  135.     t# = TIMER(.001)
  136.     MOVEPILE nDisks, 0, 2
  137.     updateScreen
  138.     _PRINTSTRING (20, 20), "Done in" + STR$(TIMER(.001) - t#) + " secs."
  139.     _DISPLAY
  140.     SLEEP
  141.  
  142. 'from sample
  143. SUB MOVEPILE (N, START, FINISH)
  144.     IF N > 1 THEN CALL MOVEPILE(N - 1, START, 3 - START - FINISH)
  145.     moveDisk START, FINISH
  146.     IF N > 1 THEN CALL MOVEPILE(N - 1, 3 - START - FINISH, FINISH)
  147.  
  148. SUB nonRecursive 'this works but is way slower than recursive method
  149.     DIM numMoves AS _INTEGER64, move AS _INTEGER64
  150.     DIM d1 AS INTEGER, td0 AS INTEGER, td1 AS INTEGER, td2 AS INTEGER, fromT AS INTEGER, toT AS INTEGER
  151.     t# = TIMER(.001)
  152.     numMoves = 2 ^ nDisks - 1
  153.     d1 = 0
  154.  
  155.     move = 1
  156.     WHILE move <= numMoves
  157.         td0 = td(0): td1 = td(1): td2 = td(2)
  158.         'PRINT td0, td1, td2
  159.         '_KEYCLEAR
  160.         'INPUT "OK press enter.. "; wate$
  161.         '_DISPLAY
  162.  
  163.         IF move MOD 2 = 1 THEN
  164.             fromT = d1
  165.             toT = (d1 + 1) MOD 3
  166.             d1 = toT
  167.         ELSE
  168.             IF td0 = 1 THEN
  169.                 IF td1 = 0 THEN
  170.                     fromT = 2: toT = 1
  171.                 ELSEIF td2 = 0 THEN
  172.                     fromT = 1: toT = 2
  173.                 ELSEIF td1 < td2 THEN
  174.                     fromT = 1: toT = 2
  175.                 ELSE
  176.                     fromT = 2: toT = 1
  177.                 END IF
  178.             ELSEIF td1 = 1 THEN
  179.                 IF td0 = 0 THEN
  180.                     fromT = 2: toT = 0
  181.                 ELSEIF td2 = 0 THEN
  182.                     fromT = 0: toT = 2
  183.                 ELSEIF td0 > td2 THEN
  184.                     fromT = 2: toT = 0
  185.                 ELSE
  186.                     fromT = 0: toT = 2
  187.                 END IF
  188.             ELSEIF td2 = 1 THEN
  189.                 IF td0 = 0 THEN
  190.                     fromT = 1: toT = 0
  191.                 ELSEIF td1 = 0 THEN
  192.                     fromT = 0: toT = 1
  193.                 ELSEIF td0 < td1 THEN
  194.                     fromT = 0: toT = 1
  195.                 ELSE
  196.                     fromT = 1: toT = 0
  197.                 END IF
  198.             END IF
  199.         END IF
  200.         moveDisk fromT, toT
  201.         move = move + 1
  202.     WEND
  203.  
  204.     updateScreen
  205.     _PRINTSTRING (20, 20), "Done in" + STR$(TIMER(.001) - t#) + " secs."
  206.     _DISPLAY
  207.     SLEEP
  208.  
  209.  
  210. SUB nonRecursive1 'this works but is way slower than recursive method
  211.     DIM numMoves AS _INTEGER64, move AS _INTEGER64
  212.     DIM d1 AS INTEGER, d2 AS INTEGER, d3 AS INTEGER, dv2 AS INTEGER, dv3 AS INTEGER, fromT AS INTEGER, toT AS INTEGER
  213.     t# = TIMER(.001)
  214.     numMoves = 2 ^ nDisks - 1
  215.     d1 = 0
  216.  
  217.     move = 1
  218.     WHILE move <= numMoves
  219.         'td0 = td(0): td1 = td(1): td2 = td(2) 'these can be eliminated with function td()
  220.         'PRINT td0, td1, td2
  221.         '_KEYCLEAR
  222.         'INPUT "OK press enter.. "; wate$
  223.         '_DISPLAY
  224.  
  225.         IF move MOD 2 = 1 THEN 'move disk #1 up 1 and then get the other to tower names and use those to get disk values in tower
  226.             fromT = d1
  227.             toT = (d1 + 1) MOD 3
  228.             d1 = toT
  229.         ELSE
  230.             d2 = (d1 + 1) MOD 3: d3 = (d2 + 1) MOD 3 'the two towers disk #1 is not
  231.             IF nT(d2) = 0 THEN dv2 = 0 ELSE dv2 = tower(d2, nT(d2)) 'the value of the top disk of each tower
  232.             IF nT(d3) = 0 THEN dv3 = 0 ELSE dv3 = tower(d3, nT(d3)) 'add dv2, dv3 for next move
  233.  
  234.             IF dv2 = 0 THEN
  235.                 fromT = d3: toT = d2
  236.             ELSEIF dv3 = 0 THEN
  237.                 fromT = d2: toT = d3
  238.             ELSEIF dv2 < dv3 THEN
  239.                 fromT = d2: toT = d3
  240.             ELSE
  241.                 fromT = d3: toT = d2
  242.             END IF
  243.         END IF
  244.         moveDisk fromT, toT
  245.         move = move + 1
  246.     WEND
  247.  
  248.     updateScreen
  249.     _PRINTSTRING (20, 20), "Done in" + STR$(TIMER(.001) - t#) + " secs."
  250.     _DISPLAY
  251.     SLEEP
  252.  
  253.  
  254. FUNCTION td (t)
  255.     FOR i = nDisks TO 1 STEP -1
  256.         IF tower(t, i) THEN td = tower(t, i): EXIT FUNCTION
  257.     NEXT
  258.  
« Last Edit: March 03, 2019, 02:58:48 pm by bplus »

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: the TOWERS OF HANOI
« Reply #16 on: March 03, 2019, 03:54:32 pm »
Hi Bplus
please gives to Ceasar that is of Cesar

the hanoi tower that I have posted in original code and then translated to QB64 is a sample code of TurboBasic 1.0 packaging.
My is the only translation, the algorithm is not mine!
Programming isn't difficult, only it's  consuming time and coffee

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: the TOWERS OF HANOI
« Reply #17 on: March 14, 2019, 11:39:40 am »
@Tempo, you are Italian and spell Caesar incorrectly (I think that he was most probably Roman)!

Tempo, bplus and Ron, some years ago I did think about writing a Towers of Hanoi program.  It looks like you have the logic completely solved, although the mere mention of 'recursion' has me flummoxed.  The program would look rather nicer with 3D disks on a 3D pyramid.  When I've learnt some OpenGL from Ashish, I may start a project with this in mind.  Don't hold your breaths, though!

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: the TOWERS OF HANOI
« Reply #18 on: March 14, 2019, 12:10:09 pm »
Qwerkey
:-) lol you're right it is mispelled but I think that it is probably more mistyped!
the real name is nor Ceasar nor Cesare but Gaius Iulius Caesar https://en.wikipedia.org/wiki/Julius_Caesar
who turned the Roman Republic to the Roman Empire.

I'm waiting for the 3D Hanoi Tower... with or without OpengGl....
Programming isn't difficult, only it's  consuming time and coffee