代表 Haskell 中的棋盘

Representing a chessboard in Haskell

我正在尝试在 Haskell 中实现一个函数,该函数 returns 一个列表,其中包含玩家的所有可能动作。该函数的唯一参数是一个字符串,由棋盘的实际状态(在 Forsyth-Edwards Notation 中)和移动玩家(b/w)组成。

符号示例:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w(起始板状态)

移动以 [origin]-[destination] 形式的字符串形式传输。目的地始终是 [column][row] 形式的位置,其中左下角的方块称为 a1,右上角的方块称为 h8。例如,移动是移动“b3-c4”。 (没有castling/En-passant)。

在 Java 中,我会为电路板使用二维数组,但在 Haskell 中,我找不到类似的解决方案(我是函数式编程的新手)。

用什么 way/data 结构来表示棋盘?

Data.Vector,按索引进行固定时间查找。

棋盘可以表示为Vector (Vector (Maybe Piece))。要定义 Piece,请参阅 ADTs

存储棋盘状态有两个主要选项。第一个是 Maybe 的二维列表,其中一块将表示为,例如Just $ Piece Black King 和空白方块将表示为 Nothing。这优化了确定一个正方形是否被占用的列表(如果您打算稍后添加渲染,这可能很重要):

type Board = Vector (Vector (Maybe Piece))

data Piece = Piece { color :: Color
                   , type  :: PieceType }

第二个选项是存储棋子列表及其位置。此实现可以更快地枚举所有棋子的位置,但检查特定方格上是否有棋子的速度较慢:

type Pieces = [Placement]

type Placement = { position :: Position
                 , piece    :: Piece }

data Position = 
    Pos { rank :: Int
        , file :: Int }
    deriving (Show, Eq)

data Piece = 
    Piece { color :: Color
          , ptype :: PieceType }
    deriving Show

编辑:值得注意的是,在 8x8 网格和板上最多 32 块的情况下,除非您进行大量计算,否则任何一种方式对性能的影响都将是最小的。