"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