home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
gofer230.zip
/
Progs
/
Gofer
/
Demos
/
Luc
/
horse1.gs
< prev
Wrap
Text File
|
1994-06-23
|
4KB
|
188 lines
-- Graphical Knights-Tour program : --------------------------------------------
--
--
-- author : Luc Duponcheel
--
--
-- when typing
--
-- ? showHorses ""
--
-- the program should produce on your terminal something like :
--
-- 01 64 53 58 03 60 51 34
-- 54 57 02 61 52 35 04 49
-- 63 30 55 46 59 50 33 22
-- 56 43 62 31 36 21 48 05
-- 29 14 45 42 47 32 23 20
-- 44 41 28 15 18 37 06 09
-- 13 16 39 26 11 08 19 24
-- 40 27 12 17 38 25 10 07
-- (93975 reductions, 179126 cells)
--
-- (with odd numbers in inverse-video)
--
--
-- On a Sun SPARC the program has to run in a shell tool
-- ^^^^^
--
-- On my Amiga I can also experiment with colours ...
--
--
-- The following well known strategy is used :
--
-- choose a move is which is such that,
-- after having done the move,
-- a minimal number of next moves is possible.
--
--
-- If your computer is `slow enough' then you will notice that finding such a
-- move takes longer in the beginning than at the end of the move sequence.
--
--
-- all attempts to find a faster solution are encouraged
-- ^^^^^^
--
-- PS:
--
-- if you want to avoid that your boss can see that you are
-- playing silly games at work, then you can always type in
--
-- ? clearscreen ""
--
--------------------------------------------------------------------------------
--
-- the general purpose function
-- revcomp
-- composes a list of functions in reverse order
--
revcomp :: [a -> a] -> a -> a
revcomp [] = id
revcomp (f:fs) = revcomp fs . f
--
-- some screen oriented functions
-- it is possible that you'll have to
-- redefine them if you do not work with
-- an ANSI-compliant terminal.
--
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
continue = normal . goto 0 20
-- main types
type Horse = (Int,Int)
type Horses = [Horse]
type PartOfBoard = [(Int,Int)]
-- all possible moves from (u,v) to (x,y)
(|-->) :: Horse -> Horse -> Bool
(u,v) |--> (x,y) = (x == u+1) && (y == v-2) ||
(x == u-2) && (y == v-1) ||
(x == u-2) && (y == v+1) ||
(x == u+2) && (y == v-1) ||
(x == u+2) && (y == v+1) ||
(x == u+1) && (y == v+2) ||
(x == u-1) && (y == v+2)
{-
(x == u-1) && (y == v-2) -- NOT used!
-}
horsesOn :: PartOfBoard -> Horse -> Horses
horsesOn pb h = [ h' | h' <- pb, h |--> h' ]
-- strategy
(>>) :: [a] -> [b] -> Bool
_ >> [_] = True
[_] >> _ = False
(_:ms) >> (_:ns) = ms >> ns
minimalize :: (a -> [b]) -> [a] -> (a,[b])
minimalize f [h] = (h,f h)
minimalize f (h:hs) = let (k,ms) = minimalize f hs ; ns = f h in
if ns >> ms then (k,ms) else (h,ns)
-- how to find all horses ( -: stands for `minus` )
(-:) :: Eq a => [a] -> a -> [a]
(x:xs) -: y
| x == y = xs
| otherwise = x : (xs -: y)
[] -: x = []
horses :: Horses
horses = fst (moves 64)
where
moves 1 = ([(1,1)],[ (i,j) | i <- [1..8], j <- [1..8] ] -: (1,1))
moves (n+1) = let
(hs@(hn:_),b) = moves n
f = horsesOn b
(h,_) = minimalize f (f hn)
in
(h:hs,b-:h)
-- How to show a move
showMove (x,y) n = g (x,y) . f n
where g1 (x,y) = goto (2+4*x) (2+2*y)
g (x,y)
| even (x+y) = g1 (x,y) . inverse
| otherwise = g1 (x,y) . normal
f1 n
| n < 10 = showChar '0'
| otherwise = id
f n = let m = 65 - n in f1 m . shows m
-- How to show all horses
showHorses
= clearscreen . revcomp (zipWith showMove horses [1..]) . continue
--------------------------------------------------------------------------------