{- Springerproblem in Haskell Problemstellung: ---------------- Ein Springer wird an eine vorgegebene Position auf ein Schachbrett gestellt. Von dort aus soll er alle Felder des Bretts genau einmal besuchen (und nur erlaubte Züge auf dem Brett machen). Die mögliche Lösung wird ausgegeben (sofern existent). Die Lösung soll rekursiv gefunden werden und mit den zu definierenden Funktionen erstellt werden. ------------------------------------------------ Gegeben: Position auf dem Schachbrett Gesucht: Nummerierung aller Felder für eine Tour auf dem Brett. ---------------------------------------------------------------} import Char -- for GHC data Board = Brd [[Int]] type Position = (Int,Int) showBoard :: Board -> IO () showBoard (Brd b) = do showBoardLines (reverse b) -- umdrehen für die übliche Darstellung...(Sicht von Weiß) putStrLn ('\t':(foldr (\x str -> x:'\t':str) "" (take (length b) ['A','B'..]))) --Schlusszeile showBoardLines :: [[Int]] -> IO () showBoardLines [] = return () showBoardLines l@(x:xs) = do putStrLn (show (length l) ++ "\t" ++ concat (map ((++"\t").show) x)) -- Felder mit Tab trennen showBoardLines xs -- für Test einschränken (ab wann existieren Lösungen ?) boardsize :: Int boardsize = 7 empty :: Board --empty = Brd (replicate 8 (replicate 8 0)) falsch empty = Brd (replicate boardsize (replicate boardsize 0)) main :: IO () main = do (a,b) <- inputPos putStrLn ("Startposition: " ++ [numToChar a,' '] ++ show (1+b) ++ ".") case (tryPos empty 1 (a,b)) of [] -> putStrLn ("Kein Ergebnis zu Startposition " ++ [numToChar a,' '] ++ show (1+b) ++ ".") (brd:_) -> do putStrLn "Gefundenes Ergebnis:" showBoard brd -- Eingabe der Startposition und Konvertierung inputPos :: IO Position inputPos = do let limits = "a-" ++ [numToChar (boardsize-1)] ++ ", 1-" ++ show (boardsize) putStr ("Startposition xy (" ++ limits ++ ") eingeben: ") input <- getLine if (length input < 2) then again else let x = (toLower.head) input y = (read (dropWhites (tail input))):: Int pos = (charToNum x,y-1) in if (not (validPos pos)) then again else return pos where again = do print "Falsches Eingabeformat (bitte nochmal)" inputPos dropWhites = dropWhile isSpace -- Helpers: ----------- -- Eingabekonvertierung: charToNum :: Char -> Int charToNum c = fromEnum c - fromEnum 'a' numToChar :: Int -> Char numToChar n = chr (n+97) -- Positionen auf Gültigkeit prüfen validPos :: Position -> Bool validPos (a,b) = and [a>=0,a <= limit,b>=0, b<=limit] where limit = boardsize-1 ------------------------------------------------------------------------------- -- Liste der erlaubten Züge moves :: Position -> Board -> [Position] moves _ _ = [] -- To Do... markPosition :: Int -> Position -> Board -> Board markPosition _ _ _ = empty -- To Do... -- backtracking-Algorithmus: --tryPos :: ??? tryPos _ _ _ = [] -- To Do...