我正在嘗試在 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 的值。知道為什么會這樣嗎?
我不是在尋找代碼解決方案,如果有人可以在概念上指出我正確的方向,我將不勝感激。這適用于僅限于串列處理的專案,因此不允許使用除串列或元組之外的其他資料結構。
uj5u.com熱心網友回復:
這段代碼有兩個問題:
模式順序:在您的示例中,您在測驗代碼的
(2,2)位置時會收到錯誤訊息。這是因為模式(_, k)早于(j, k),所以您檢查“上、左、右、左上、右上”,而不是您預期的“上、左、左上”模式中的變數:模式與代碼中
(_, k)的其他值成功匹配,(x, y)并且它下面的模式重疊。您只是分配k給y,而不是比較它們
因此,您可以撰寫這樣的代碼(我使用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)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/445995.html
標籤:哈斯克尔
上一篇:如何定義段函式
下一篇:HaskellRSA加密
