From: Mart Lubbers Date: Mon, 7 Mar 2016 14:05:18 +0000 (+0100) Subject: sokoban parser done X-Git-Url: https://git.martlubbers.net/?a=commitdiff_plain;h=ce272707c750ffd26760802cde66e8da29c246b7;p=mc1516pa.git sokoban parser done --- diff --git a/code/.gitignore b/code/.gitignore new file mode 100644 index 0000000..bf86cd0 --- /dev/null +++ b/code/.gitignore @@ -0,0 +1,2 @@ +Clean System Files +a.out diff --git a/code/Sokoban.dcl b/code/Sokoban.dcl index 32b5e11..631cf7d 100644 --- a/code/Sokoban.dcl +++ b/code/Sokoban.dcl @@ -1,9 +1,11 @@ definition module Sokoban -:: SokobanPuzzle = { - width :: Int, - height :: Int, - data :: [[SokobanTile]]} +from StdString import class toString + +:: SokobanPuzzle = Sokoban [[SokobanTile]] :: SokobanTile = Wall | Free | Box | Target | Agent +instance toString SokobanTile +instance toString SokobanPuzzle + parse :: String *World -> (SokobanPuzzle, *World) diff --git a/code/Sokoban.icl b/code/Sokoban.icl new file mode 100644 index 0000000..9102bc1 --- /dev/null +++ b/code/Sokoban.icl @@ -0,0 +1,60 @@ +implementation module Sokoban + +import StdFile +import StdList +import StdString +import StdMisc + +Start :: *World -> (String, *World) +Start w +# (s, w) = parse "../sokobanzip/screens/screen.1" w += ("\n" +++ toString s, w) + +instance toString SokobanPuzzle where + toString (Sokoban []) = "" + toString (Sokoban [[]:rows]) = "\n" +++ toString (Sokoban rows) + toString (Sokoban [[x:xs]:rows]) = + toString x +++ toString (Sokoban [xs:rows]) + +instance toString SokobanTile where + toString Free = " " + toString Wall = "#" + toString Box = "$" + toString Agent = "@" + toString Target = "." + +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" +# (ok, w) = fclose f w +| not ok = abort "Couldn't close file" += (Sokoban (parseRows contents), w) + +parseRows :: [Char] -> [[SokobanTile]] +parseRows cs = case parseRow cs of + ([], _) = [] + (x, rest) = [x:parseRows rest] + +parseRow :: [Char] -> ([SokobanTile], [Char]) +parseRow [] = ([], []) +parseRow ['\n':xs] = ([], xs) +parseRow [x:xs] +# (rest, xs) = parseRow xs +# current = case x of + '#' = Wall + '$' = Box + '@' = Agent + '.' = Target + ' ' = Free + _ = abort ("Unknown char: '" +++ toString x +++ "'") += ([current:rest], xs) + +readEntireFile :: *File -> *([Char], *File) +readEntireFile f +# (b, c, f) = freadc f +| not b = ([], f) +# (cs, f) = readEntireFile f += ([c:cs], f)