toString Box = "$"
toString Agent = "@"
toString Target = "."
+ toString TargetBox = "*"
+ toString TargetAgent = "+"
+
+parseFromFile :: *File -> (SokobanPuzzle, *File)
+parseFromFile f
+# (contents, f) = readEntireFile f
+| isEmpty contents = abort "File is empty or unreadable"
+= (Sokoban (parseRows contents), f)
parse :: String *World -> (SokobanPuzzle, *World)
parse fp w
# (ok, f, w) = fopen fp FReadText w
| not ok = abort ("Couldn't open file: '" +++ fp +++ "'")
-# (contents, f) = readEntireFile f
-| isEmpty contents = abort "File is empty or unreadable"
+# (puzzle, f) = parseFromFile f
# (ok, w) = fclose f w
| not ok = abort "Couldn't close file"
-= (Sokoban (parseRows contents), w)
+= (puzzle, w)
+
+numberOfBlocks :: SokobanPuzzle -> Int
+numberOfBlocks (Sokoban bs) = let fbs = flatten bs in
+ length ([1\\(Box)<-fbs] ++ [1\\(TargetBox)<-fbs])
parseRows :: [Char] -> [[SokobanTile]]
parseRows cs = case parseRow cs of
'$' = Box
'@' = Agent
'.' = Target
+ '+' = TargetAgent
+ '*' = TargetBox
' ' = Free
_ = abort ("Unknown char: '" +++ toString x +++ "'")
= ([current:rest], xs)