检查二维数组中的邻居时出错

格雷格詹姆斯

我正在尝试在 Haskell 中为类实现 Conway 的游戏,并使用如下代码来检查大小为 (w,h) 的方板上的单元格 (x,y) 的邻居:

liveNeighbors :: ((Int,Int), [[Bool]]) -> (Int,Int) -> Int
liveNeighbors arr@((w,h), cells) (x,y) =
    let
        j = w -1
        k = h - 1
        checkcell (x,y) = if (cells !! y) !! x then 1 else 0 in
    case (x,y) of
    -- Check right, bottom, and bottom right
    (0,0) -> checkcell (x,y+1) + checkcell (x+1,y) + checkcell (x+1,y+1)
    -- Check bottom, left, right, bottom left, bottom right
    (_,0) -> checkcell (x,y+1) + checkcell (x-1,y) + checkcell (x+1,y)
             + checkcell (x+1,y+1)  + checkcell (x-1,y+1)
    -- check bottom, top, right, top right, bottom right
    (0,_) -> checkcell (x,y+1)  + checkcell (x,y-1)  + checkcell (x+1,y)
             + checkcell (x+1,y+1)  + checkcell (x+1,y-1)
    -- check top, left, right,top left, top right
    (_, k) -> checkcell (x,y-1)  + checkcell (x-1,y)  + checkcell (x+1,y)
             + checkcell (x-1,y-1)  + checkcell (x+1,y-1)
    -- check bottom, top, left, top left, bottom left
    (j, _) -> checkcell (x,y+1)  + checkcell (x,y-1)  + checkcell (x-1,y)
             + checkcell (x-1,y+1)  + checkcell (x-1,y-1)
    -- check top, left, top left
    (j,k) -> checkcell (x,y-1)  + checkcell (x-1,y)  + checkcell (x-1,y-1)
    -- check bottom, left, bottom left
    (j,0) -> checkcell (x,y+1)  + checkcell (x-1,y)  + checkcell (x-1,y+1)
    -- check top, top right, right
    (0,k) -> checkcell (x,y-1)  + checkcell (x+1,y-1)  + checkcell (x+1,y)
    -- check all surrounding
    (_,_) -> checkcell (x,y+1)  + checkcell (x,y-1)  + checkcell (x+1,y)
             + checkcell (x-1,y)  + checkcell (x+1,y+1) + checkcell (x+1,y-1)
             + checkcell (x-1,y+1)  + checkcell (x-1,y-1)

我正在使用jandk来适应数组的边界。我正在检查所有边缘情况和角落,但是代码在 , 处的数组大小和行失败(_, max_row)并且给出了不正确的值。这是 ghci 给我的输出:(max_column, _)(max_column, max_row)

> world = ((3,3), [[False, False, False], [False, False, False], [False, True,True]])
> liveNeighbors world (2,2)
*** Exception: Prelude.!!: index too large
> liveNeighbors world (0,2)
*** Exception: Prelude.!!: index too large
> liveNeighbors world (0,1)
1
> liveNeighbors world (1,1)
0

的值(1,1)应该是 2,因为右下角和右下角都是真的,但是它只给出 1 的值。知道为什么会这样吗?

我不是在寻找代码解决方案,如果有人可以在概念上指出我正确的方向,我将不胜感激。这适用于仅限于列表处理的项目,因此不允许使用除列表或元组之外的其他数据结构。

谢尔盖库兹1001

这段代码有两个问题:

  1. 模式顺序:在您的示例中,您在测试代码的(2,2)位置时会收到错误消息。这是因为模式(_, k)早于(j, k),所以您检查“上、左、右、左上、右上”,而不是您预期的“上、左、左上”

  2. 模式中的变量:模式与代码中(_, k)的其他值成功匹配,(x, y)并且它下面的模式重叠。您只是分配ky,而不是比较它们

因此,您可以编写这样的代码(我使用MultiWayIf扩展名来与原始代码更加相似,但这只是语法糖):

{-# LANGUAGE MultiWayIf #-}

neighbors :: ((Int,Int), [[Bool]]) -> (Int,Int) -> Int
neighbors arr@((w,h), cells) (x,y) = 
    let 
        j = w -1
        k = h - 1 
        checkcell (x,y) = if (cells !! y) !! x then 1 else 0 in 
    if
        -- Check right, bottom, and bottom right
        | (x, y) == (0,0) -> checkcell (x,y+1) + checkcell (x+1,y) + checkcell (x+1,y+1)
        --check top, left, top left
        | (x, y) == (j,k) -> checkcell (x,y-1)  + checkcell (x-1,y)  + checkcell (x-1,y-1) 
        --check bottom, left, bottom left
        | (x, y) == (j,0) -> checkcell (x,y+1)  + checkcell (x-1,y)  + checkcell (x-1,y+1) 
        -- check top, top right, right
        | (x, y) == (0,k) -> checkcell (x,y-1)  + checkcell (x+1,y-1)  + checkcell (x+1,y) 
        -- Check bottom, left, right, bottom left, bottom right
        | y == 0 -> checkcell (x,y+1) + checkcell (x-1,y) + checkcell (x+1,y)  + checkcell (x+1,y+1)  + checkcell (x-1,y+1) 
        --check bottom, top, right, top right, bottom right
        | x == 0 -> checkcell (x,y+1)  + checkcell (x,y-1)  + checkcell (x+1,y)  + checkcell (x+1,y+1)  + checkcell (x+1,y-1) 
        -- check top, left, right,top left, top right
        | y == k -> checkcell (x,y-1)  + checkcell (x-1,y)  + checkcell (x+1,y)  + checkcell (x-1,y-1)  + checkcell (x+1,y-1) 
        -- check bottom, top, left, top left, bottom left
        | x == j -> checkcell (x,y+1)  + checkcell (x,y-1)  + checkcell (x-1,y)  + checkcell (x-1,y+1)  + checkcell (x-1,y-1) 
        --check all surrounding 
        | otherwise -> checkcell (x,y+1)  + checkcell (x,y-1)  + checkcell (x+1,y)  + checkcell (x-1,y)  + checkcell (x+1,y+1)  +checkcell (x+1,y-1)  + checkcell (x-1,y+1)  + checkcell (x-1,y-1)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章