Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

"Towers of Hanoi" : Comments please

 [1/3] from: rgombert::essentiel::net at: 18-Feb-2001 21:05


Hi, This is one of my first scripts with REBOL. As i'm not sure of the "better" way to achieve things, i would be happy to receive your comments about this script, and how to code it better, or closer to the REBOL coding 'spirit'. Thanks, Renaud email: [rgombert--essentiel--net] ICQ# 2602184 REBOL [ Title: "Hanoi game (learnig Rebol with...)" Author: "Renaud GOMBERT" Email: "[rgombert--essentiel--net]" Purpose: { The "Towers of Hanoi" Game. Discs of different sizes stays on 3 sticks/stacks. Move one disc at a time from one stack to another. A move is possible only if the destination stick is empty or its top disc is greater than the the one you are moving. The goal is to move the initial stack from the first stick to an other. } ] init: func [ "Initialisation of the hanoi block" n [integer!] "Number of disc to use" /local tmp ][ count: make integer! 0; tmp: make block! [] hanoi: make block! [] for i 1 n 1 [tmp: append tmp i] hanoi: reduce [tmp make block! 0 make block! 0] ] first2: func [ "Return first item, otherwise 99999" blk [block!] ][ if (length? blk) = 0 [return 99999] return first blk ] move: func [ "Move one disc from one stick to another - does not care of game's rules" from [integer!] to [integer!] /local temp tmp ][ temp: make block! [[][][]] tmp: first pick hanoi from for i 1 3 1 [ poke temp i head either i = from [remove hanoi/:i] [either i = to [insert head hanoi/:i tmp][hanoi/:i]] ] count: count + 1 hanoi: copy temp print [count ": move from" from "to" to " : " mold hanoi] ] play: func [ "Play nb disc from one place to an other" from [integer!] "Place to start from" to [integer!] "Place to go to" nb [integer!] "How many disc to move" /local from_state to_state tmp n ][ tmp: pick [0 0 3 2 1] (from + to) either ((length? pick hanoi from) > 0) [ either nb = 1 [ from_state: pick hanoi from to_state: pick hanoi to either (first2 from_state) < (first2 to_state) move from to ][ move to from play from to 2 ] play from tmp (nb - 1) play from to 1 play tmp to (nb - 1) ] ][ print "Can't do that: nothing to move" ] ] ; init a game with 4 discs init 4 ;play the game play 1 3 4

 [2/3] from: dockimbel:free at: 19-Feb-2001 19:49


Hi Renaud, Don't know if i have the "rebol coding spirit" :) but this is how i would write some parts of your script :
> init: func [ > "Initialisation of the hanoi block"
<<quoted lines omitted: 7>>
> hanoi: reduce [tmp make block! 0 make block! 0] > ]
; /local tmp i [ i: count: 0 ; "make integer!" is not necessary. tmp: make block! n ; pre-allocate n item for the new block. loop n [ ; 'loop is easier to read and much faster. append tmp i ; tmp will be modify, no need to re-assign. i: i + 1 ] hanoi: reduce [tmp copy [] copy []] ]
> first2: func [ > "Return first item, otherwise 99999"
<<quoted lines omitted: 3>>
> return first blk > ]
[ either empty? blk [99999][first blk] ; you can see 'empty? as a shortcut to 'zero? 'length? ]
> move: func [ > "Move one disc from one stick to another - does not care of game's rules"
<<quoted lines omitted: 3>>
> ][ > temp: make block! [[][][]]
you could also use : array/initial [3 1] []
> tmp: first pick hanoi from > for i 1 3 1 [
<<quoted lines omitted: 5>>
> print [count ": move from" from "to" to " : " mold hanoi] > ]
Your code is a little hard to read here. You should indent it after reading the "Style Guide" part of the Rebol manual. (also, not sure that 'head is needed here.)
> play: func [ > "Play nb disc from one place to an other"
<<quoted lines omitted: 5>>
> tmp: pick [0 0 3 2 1] (from + to) > either ((length? pick hanoi from) > 0) [
either not empty? pick hanoi from [
> either nb = 1 [ > from_state: pick hanoi from
<<quoted lines omitted: 17>>
> ;play the game > play 1 3 4
Pretty good script for learning Rebol. (A quand une version /View ? ;) ) HTH, DocKimbel.

 [3/3] from: rgombert:essentiel at: 19-Feb-2001 22:02


Thanks Nenad, your comments are of great help for me. My code is indented, but with tabs... wich have disapeared in the mail. Sorry, i'll take care about this for next postings. As you sugest, a next release will be a /View one... but now i don't know how to make widgets move on a layout : i've just started to learn /Core and /View. To learn, i'm also writing a webpage checker. The /Core version is working, and i'm curently "dressing" it with /View. I'll post it here if i'm not boring you with my scripts. The actual /Core version stay below... but haven't yet been modified regarding of Nenad's comments... except for my indentation, that i've tried to conserve. REBOL [ Title: "Web Page Change Detector" File: %checkweb.r Date: 19-Feb-2001 Purpose: { Determine if a web pages has changed since it was last checked. } Category: [web file net 2] ] ;### Where the script is script-path: "scripts/" ;### Add a site to check addsite: func [ /local name url ] [ print "ADDING A WEBPAGE TO THE LIST : " name: ask "Page name : " url: make url! ask "Page URL : " url: make block! append (append (append [] name) url) 0 webdata: append/only webdata url save make file! reduce [script-path "webs.rdata"] webdata ] ;### LOAD data file either exists? %webs.rdata [ webdata: load %webs.rdata ][ webdata: make block! [] print "DATAFILE IS NOT ACCESSIBLE... creating one" addsite ] ;### go to the website - work only within /View goweb: func [i] [browse pick webdata/:i 2] ;### Do all the checkings checkweb: func [ /local i changed /go ][ changed: false i: make integer! 0 foreach site webdata [ i: i + 1 page-sum: checksum read site/2 prin ["[" i "]> " site/1] either page-sum = site/3 [ print " cheked." ][ poke site 3 page-sum print [" HAS CHANGED (" site/2 ")"] if go [goweb i] changed: true ] ] if changed [save make file! reduce [script-path "webs.rdata"] webdata] print "WEBPAGES CHECK DONE." ]

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted