[Haskell-cafe] How can I represent 4x4 map in haskell

Richard A. O'Keefe ok at cs.otago.ac.nz
Tue Apr 1 21:40:49 EDT 2008

On 1 Apr 2008, at 3:51 am, iliali16 wrote:
> so my question is if this is ok to represent a map. If yes I will  
> try to
> write the function which makes it 4 x 4 myself. What I jsut need as an
> answer is Yes or No. Just to let you know is that I am trying to  
> build the
> Wumpus World

What you should know is that there is no rule that the Wumpus World
has to be 4 x 4.  Quoting
"The size of the grid may vary for different scenarios."

You are tacitly assuming that if you want to know what's where in the
wumpus world you have to store an *image* of that world.  But this is
not so.

	The wumpus may be dead, in which case we don't care where it is,
	or it may be in some specific location:
		wumpus :: Maybe Location
	The gold may have been grabbed, in which case we know where it is
	without looking (we have it), or it may be in some specific place:
		gold :: Maybe Location
	In some versions of the wumpus world, there may be more than one
	piece of gold.  In that case,
		gold :: [Location]
	There is some number of pits.  There might be none.  All we really
	want to know is whether a particular square is a pit or not.
		is_pit :: Location -> Bool

	It's not clear to me whether the gold or the wumpus might be in a
	pit.  Since it's deadly to enter a pit anyway, we don't really care.
	The gold and the wumpus might well be in the same cell.

So we can do this:

	type Location = (Int, Int)

	data Wumpus_World
	   = Wumpus_World {
		bounds :: Location,
		wumpus :: Maybe Location,
		gold   :: Maybe Location,
		is_pit :: Location -> Bool

	initial_world = Wumpus_World {
	    bounds = (4,4),
     	    wumpus = Just (3,3),
	    gold   = Just (3,3),
	    is_pit = \loc -> case loc of
				(2,1) -> True
				(4,3) -> True
				_     -> False
	} -- I just made this one up

	holds :: Eq a => Maybe a -> a -> Bool

	holds (Just x)  y = x == y
	holds (Nothing) _ = False

	has_wumpus, has_gold :: Wumpus_World -> Location -> Bool

	has_wumpus world location = wumpus world `holds` location

	has_gold world location = wumpus world `holds` location

There are lots of other ways to do this, and whether this is a
good one depends on what you need to do with it.  It might be
better to have

	has_wumpus :: Location -> Bool
	has_gold   :: Location -> Bool

as the field members directly, for example.  One thing that is
right about it is that it doesn't build in any specific idea of
the size of the world.  Another good thing is that it postpones
the decision about how to tell where the pits are.

But of course there are two maps: the complete map of how the world
really is, which the world simulator has to have, and the "agent's"
partial map recording what it has seen so far.  They might have
similar representations, or they might not.

It's a really good idea to write as much of the code as you can so
that it doesn't know what the map representation is.

More information about the Haskell-Cafe mailing list