home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
gofer230.zip
/
Progs
/
Gofer
/
Demos
/
Luc
/
hanoi2.gs
< prev
next >
Wrap
Text File
|
1994-06-23
|
3KB
|
105 lines
-- Graphical Towers-Of-Hanoi program : -----------------------------------------
--
--
-- author : Luc Duponcheel
--
--
-- The program makes use of screen-oriented functions.
-- It is possible that you'll have to redefine them if
-- you do not work with an ANSI-compliant terminal.
--
--------------------------------------------------------------------------------
-- general purpose function `comp' composes a list of functions
comp :: [a -> a] -> a -> a
comp [] = id
comp (f:fs) = f . comp fs
-- screen oriented functions
escape = showChar '\ESC' . showChar '['
inverse = escape . showString "7m"
normal = escape . showString "m"
goto x y = escape . shows y . showChar ';' . shows x . showChar 'H'
clearscreen = showString "\ESC[2J" -- ANSI version
clearscreen = showChar '\^L' -- Sun window
start = clearscreen
stop = normal
-- how to put and get a disk
showSpace = showString . space
putDisk n x y = inverse . goto (n-x) y . showSpace (2*x)
getDisk n x y = normal . goto (n-x) y . showSpace (2*x)
-- next configuartion
next ((a:as),bs,cs) (0,1) = (as,(a:bs),cs)
next ((a:as),bs,cs) (0,2) = (as,bs,(a:cs))
next (as,(b:bs),cs) (1,0) = ((b:as),bs,cs)
next (as,(b:bs),cs) (1,2) = (as,bs,(b:cs))
next (as,bs,(c:cs)) (2,0) = ((c:as),bs,cs)
next (as,bs,(c:cs)) (2,1) = (as,(c:bs),cs)
-- action to be performed
action n ((a:as),bs,cs) (0,1)
= getDisk (2*n) a (2*n - length as) . putDisk (5*n) a (2*n - length bs)
action n ((a:as),bs,cs) (0,2)
= getDisk (2*n) a (2*n - length as) . putDisk (8*n) a (2*n - length cs)
action n (as,(b:bs),cs) (1,0)
= getDisk (5*n) b (2*n - length bs) . putDisk (2*n) b (2*n - length as)
action n (as,(b:bs),cs) (1,2)
= getDisk (5*n) b (2*n - length bs) . putDisk (8*n) b (2*n - length cs)
action n (as,bs,(c:cs)) (2,0)
= getDisk (8*n) c (2*n - length cs) . putDisk (2*n) c (2*n - length as)
action n (as,bs,(c:cs)) (2,1)
= getDisk (8*n) c (2*n - length cs) . putDisk (5*n) c (2*n - length bs)
-- how to show the initial configuration
showInit n = comp [ putDisk (2*n) x (y+n) | (x,y) <- zip [1..n] [1..n] ]
-- the actual moves
moves n cnfg [] = []
moves n cnfg (x:xs) = move : moves n nextcnfg xs
where
nextcnfg = next cnfg x
move = action n cnfg x
-- how to show the moves
showMoves n = comp (moves n ([1..n],[],[]) (hanoi n [0,2,1]))
-- main code (simple!)
hanoi 0 [a,b,c] = []
hanoi n [a,b,c] = hanoi (n-1) [a,c,b] ++ [(a,b)] ++ hanoi (n-1) [c,b,a]
-- how to show it all
showHanoi n = start . showInit n . showMoves n . stop
--------------------------------------------------------------------------------