2016-11-30 71 views
2

我正在開發一個通用版本的遊戲連接4,您可以在其中選擇網格的大小以及數字爲了獲勝而需要連接的棋子。我正在研究一個能夠檢查哪個球員獲勝的功能。我試圖把它分成四個小部分。我已經實現了一個函數來返回列,但是在行和網格上的對角線都被卡住了。我是Haskell的新手,我正努力停止以OO方式思考這些問題。任何幫助將不勝感激,因爲我一直在這個問題上停留了很長一段時間。Haskell - 如何返回一個網格中所有行元素的列表列表

import Data.Maybe 
import Data.List 

data Piece = Yellow | Red  

type Column = [Piece] 
type Board = [Column] 

data BoardState = BS { 
    theBoard :: Board, 
    lastMove :: Piece, 
    numColumns :: Int, 
    numRows :: Int, 
    numToConnect :: Int } 

repeatNothing :: Int -> [Maybe a] 
repeatNothing m = replicate m Nothing 

padN :: [a] -> Int -> [Maybe a] 
padN xs n = (map Just xs) ++ repeatNothing (n - (length xs)) 

columns :: BoardState -> [[Maybe Piece]] 
columns bs = map (\col -> padN col (numRows bs)) (theBoard bs) 

rows :: BoardState -> [[Maybe Piece]] 
rows bs = map (\row -> padN row (numColumns bs)) (theBoard bs) 

diagonalsForward :: BoardState -> [[Maybe Piece]] 
diagonalsForward = undefined 

diagonalsBackward :: BoardState -> [[Maybe Piece]] 
diagonalsBackward = undefined 
+0

對於這個遊戲,我可能會通過索引結構而不是列表列表來代表董事會。甚至可能是'Data.Map(Int,Int)Piece'。然後查找行列和對角線的複雜性主要是生成適當的[[(Int,Int)]列表,這應該是一些簡單的列表解析。 – luqui

+0

我會建議定義'數據片=黃色|紅色| None'而不是返回'MaybePiece' –

回答

1

既然你說你學習Haskell,我將只是給你一些提示:

  1. 如果你有[[1, 2, 3], [4, 5, 6], [7, 8, 9]]爲列的列表,然後行的列表[[1, 4, 7], [2, 5, 8], [3, 6, 9]]正好是列的transpose

  2. 的主對角線的列(牆倒右)(x:_):csx其次是主對角線的列cs的,沒有他們的第一行。

  3. 所有(右下去)列的對角線c:cs是對角線的c:cs隨後列的所有對角線cs

  4. 要獲得對角線去左下方,它足以reverse列的順序,然後得到右下角的對角線。

0

如果定義了件作爲一個開放的插槽

data Piece = Yellow | Red | Empty deriving Show 
let Board = replicate n $ replicate m Empty 

您可以測試是否有連續4個由圖案

pre:Yellow:Yellow:Yellow:Yellow:post 

匹配測試,如果黃有4個連續

類似的模式匹配可以在列表列表的轉置上完成。

相關問題