“Haskell”修改字符串数组中字符的方法?

时间:2013-11-15 23:14:40

标签: haskell

我不确定我们的作业是否以最具功能性的方式呈现,但我必须使用它。我有一张"地图"这代表了一个pacman游戏状态:

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

其中B是边框图块,P是pacman,_是空格,.是食品芯块。移动pacman时有很多规则,但请考虑一个:

当pacman进入由食物颗粒占据的瓷砖时,用空的空间替换pacman瓷砖,用pacman替换食物颗粒。这个函数有定义:

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

现在我已经有了函数,它给了我pacman的(x,y)坐标元组和他的新位置,我打算使用!!函数来"覆盖&# 34;瓷砖。但是,我知道一些列表操作,例如:。我可以使用:来完成这项任务吗?

3 个答案:

答案 0 :(得分:2)

我不是修改字符串,而是定义类型函数:

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

renderBoard :: Position -> Board

然后我会修改pacman的位置并重新渲染董事会:

move :: Position -> Position

编辑:要回答您的具体问题,您可以使用lens库轻松完成此操作:

import Control.Lens

move :: Position -> Position -> Board -> Board
move (oldX, oldY) (newX, newY) = (ix oldX.ix oldY .~ '_') . (ix newX.ix newY .~ 'P')

答案 1 :(得分:0)

这是一种不依赖于库的简单方法。首先,我们定义一个函数.~,允许您设置列表的索引 -

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

并给它一个方便的别名,以便我们可以使用中缀形式。

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

这允许您执行

之类的操作
>> let list = [1,2,3,4]
>> 1 .~ 10 $ list
[1,10,3,4]

现在将它扩展到修改二维列表的函数

是一件简单的事情
(n,m) .= x = \xs -> n .~ (m .~ x $ xs!!n) $ xs

以便您可以执行

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

现在您可以轻松编写一个函数move,它可以获取旧位置,新位置和当前电路板,并以您希望的方式修改电路板

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'

也就是说,where子句中的第一行修改了电路板以用空的空间替换PacMan的旧位置,第二行修改了已经重新形成的电路板,将PacMan置于新位置。

答案 2 :(得分:0)

下面是一个replace函数,可用于替换二维数组[[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]

第二个参数是需要使用第3个位置的Char值更新的位置。

使用此功能,您应该能够实现移动功能。