Tuesday, December 05, 2006

Adventures in Haskell: parsing the game world

It's been a while since my last post in Haskell, as it's hard to find the time when I spend 40 hours a week doing Java, and there's little people to take care of in the house... I have been working on my adventure game, still, mainly to separate the data from the actual code. After a fews days of tinkering, I have it working, yoohoo!
Of course, having to write a simple parser was a bit challenging given my limited knowledge of the language, and I wanted to stay with simple constructs. Hence,
I don't use any monadic stuff, I just read the data file and deal with a list of Strings, one String per line, having each method take the list and send back the remainder of list. Promise, I will look into a state monad! And I know there some advanced parsing techniques in Haskell, I mean, more advanced than reading lines and calling words on it...
I had fun with lazy IO, as any newbie Haskell programmer: using getContents seemed sometimes not to give me any lines back, until I understood than evaluating the result after closing the file handle was not the smart way to do things...
So much for the "once it compiles, it works" mantra that I was chanting last time: when parsing a file, the content matters, too, not only the code, so I had trouble solving all the unmatched pattern errors I got. I found GHC more helpful than Hugs for error messages: an error that got me scratching my head for a while in Hugs got solved as soon as I ran the same code in GHC.
I tried as well Hugs.Observe to debug my program, but I fear my grasp of lazy evaluation is too limited yet: sometimes I was sure I was getting into a method but observe was not reporting anything...
Anyway, if anybody is interested in the code, the parser code is here, and an example of a data file is here. The structure is simple enough, blank lines are used a separator and on most lines the first couple of words are keywords (item codes, location codes, etc...). The adapted game code is here (note that the path to the data file is hard-coded here)
As usual, any comments and suggestions welcome!

3 comments:

Dan said...

you should check out parsec for text parsing stuff

JP Moresmau said...

Thanks for the suggestion, my approach to Haskell is to do little things myself to grasp the fundamentals of the language, and then to start using the libraries...

Anonymous said...

learning parsec aside,

The question in my mind is why you did not simply store the data as data that the reader could understand?

[("church",[("south","cloister","A little vaulted door leads to the south")] etc