2016-11-30 70 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个连续

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

相关问题