0

I'm not sure if our assignment was presented in the most functional-enabling of ways, but I have to work with it. I have a "map" that represents a pacman game state:

B B B B
B P _ B
B . . B
B B B B

where B is a border tile, P is pacman, _ is an empty space, and . is a food pellet. There are many rules when moving pacman, but consider one:

When pacman moves into a tile occupied by a food pellet, replace the pacman tile with an empty space and the food pellet with pacman. This function would have the definition:

move:: [[Char]] -> [[Char]]

Right now I've got functions that give me the (x,y) coordinate tuple of pacman and his new location, and I was planning to use the !! function to "overwrite" the tiles. However, I know a little of list operations such as :. Could I use : to accomplish this task?

3 Answers 3

2

Rather than modify the string, I would instead define a function of type:

type Position = (Int, Int)
type Board = [[Char]]

renderBoard :: Position -> Board

Then I would just modify pacman's position and re-render the board:

move :: Position -> Position

Edit: To answer your specific question, you can do this easily using the lens library:

import Control.Lens

move :: Position -> Position -> Board -> Board
move (oldX, oldY) (newX, newY) = (ix oldX.ix oldY .~ '_') . (ix newX.ix newY .~ 'P')
Sign up to request clarification or add additional context in comments.

4 Comments

Nice tip on design, but I'm stuck with the professor's declarations unfortunately.
Updated to answer your specific question
What does ix and .~ stand for? Also, correct me if I'm wrong; is the . operator taking the changed board on the left and using that in the next lens replacement?
@CalebJares ix means "index" and (.~) is like a function setter. The idea is that the left argument of (.~) tells it what to set, and in this case it says "Set the char located at outer index oldX and inner index oldY". The right argument of .~ is what to set it to (in this case, _). It's a functional setter, meaning that it produces a function of type [[Char]] -> [[Char]]. I take two such functions and compose them using function composition, which is what the (.) is doing.
0

Below is a replace function that you can use to replace a particular position character in the 2d array [[Char]]

replace :: [[Char]] -> (Int,Int) -> Char -> [[Char]]
replace chars (x',y') c = do
  (x,row) <- zip [0..] chars
  return [if x == x' && y == y' then c else r | (y,r) <- zip [0..] row]

The second argument is the position which needs to be updated with the Char value in 3rd position.

Using this function you should be able to implement your move function.

Comments

0

Here's a simple approach that doesn't rely on libraries. First, we define a function .~ that allows you to set the index of a list -

set n x xs = take n xs ++ (x : drop (n+1) xs)

and give it a convenient alias so that we can use it in infix form.

n .~ x = \xs -> set n x xs

This allows you to do things like

>> let list = [1,2,3,4]
>> 1 .~ 10 $ list
[1,10,3,4]

Now it's a simple matter to extend that to a function that modifies two-dimensional lists

(n,m) .= x = \xs -> n .~ (m .~ x $ xs!!n) $ xs

so that you can do things like

>> let listOfList = [[1,2,3],[4,5,6],[7,8,9]]
>> (1,1) .= 100 $ listOfList
[[1,2,3],[4,100,6],[7,8,9]]

Now you can easily write a function move that takes an old position, a new position and the current board, and modifies the board in the way you want

type Pos   = (Int,Int)
type Board = [[Char]]

move :: Pos -> Pos -> Board -> Board
move (x,y) (x',y') board = board''
  where
    board'  = (x, y ) .= '_' $ board
    board'' = (x',y') .= 'P' $ board'

That is, the first line in the where clause modifies the board to replace PacMan's old position with an empty space, and the second line modifies the board that's reutrned form that, to put PacMan in the new position.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.