【问题标题】:Representing a chessboard in Haskell在 Haskell 中表示棋盘
【发布时间】:2021-02-16 12:42:23
【问题描述】:

我正在尝试在 Haskell 中实现一个函数,该函数返回一个列表,该列表包含起床玩家的所有可能动作。该函数的唯一参数是一个字符串,由棋盘的实际状态(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 中,我会为 Board 使用 2d 数组,但在 Haskell 中我找不到类似的解决方案(我是函数式编程的新手)。

什么是表示棋盘的好方法/数据结构?

【问题讨论】:

标签: haskell chess


【解决方案1】:

存储棋盘状态有两个主要选项。第一个是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 个棋子,除非您进行大量计算,否则任何一种方式的性能影响都将是最小的。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 我不能使用 Vector(仅限 Haskell 项目限制中的默认库)。也许 Data.Array 可能是另一种选择
    • 当然。 GHC haskell 提供GHC.Arr
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多