当前位置: 首页 > 知识库问答 >
问题:

在哈斯克尔代表棋盘

漆雕升
2023-03-14

我正在尝试在 Haskell 中实现一个函数,该函数返回一个列表,其中包含玩家的所有可能动作。该函数的唯一参数是一个字符串,由棋盘的实际状态(在福赛斯-爱德华兹符号中)组成,后跟移动的玩家(b/w)。

符号示例:rnbqkbnr/pppppp/8/8/8/PPPPPPP/rnbqkbnr w(起始板状态)

移动以[origin]-[destination]格式的字符串传输。目的地始终是形式[column][row]的位置,其中左下方格称为a1,右上方格称称为h8。例如,移动可以是移动“b3-c4”。(无城堡/城堡)。

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

用什么样的方式/数据结构来表示棋盘比较好?

共有2个答案

隆飞宇
2023-03-14

<code>数据。向量具有按索引进行的恒定时间查找。

棋盘可以表示为< code>Vector (Vector(可能是棋子))。要定义< code>Piece,请参见ADTs

宋俊民
2023-03-14

存储板状态有两个主要选项。第一个是可能的2D列表,其中一个部分将表示为,例如只是$Piece Black King,一个空白方块将表示为。这优化了确定方块是否被占用而不是列出块所在的位置(如果您计划稍后添加渲染,这可能很重要):

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个棋子,除非您进行大量计算,否则无论哪种方式对性能的影响都将很小。

 类似资料:
  • 我对Haskell比较陌生,我正在努力找到一种实现Haskell的span函数的方法。然而,我的问题比这更一般,因为我不知道如何使函数返回包含所需元素的列表或元组列表。我对列表的问题,例如: 是我不能让函数在列表列表中的第一个列表中添加一个元素。我只知道如何将另一个列表附加到列表列表中。 简而言之,如果您向我解释如何实现span函数,我希望这一切都会清楚。

  • :101:22:ERROR:•在表达式“count words”的第一个参数中的“hello”中,即表达式:countWords[“hello”,“hello”,“world”]中的“[”hello“,”hello“,”world“]”中,无法将预期类型“Char”与实际类型“[Char]”匹配• :101:31:error:•在表达式“count words”的第一个参数中的“world”中,即

  • Haskell(使用编译器)比您预期的要快得多。如果使用得当,它可以接近低级语言。(Haskellers最喜欢做的一件事是尝试将C语言的5%以内(甚至超过它,但这意味着您使用的是一个低效的C程序,因为GHC将Haskell编译为C)。)我的问题是,为什么?

  • Scala开发人员学习IO单元体,因此一般的蹦床技术对于不可能进行尾调用优化的递归是必要的,我想知道Haskell是如何避免它的。 我知道Haskell是一种懒惰的语言,但是我想知道是否有人可以再详细说明一下。 例如,为什么ForeverM stackoverflow不在Scala中运行?好吧,我可以回答蹦床,我可以找到实际的代码,在图书馆和博客。我自己居然实现了一个基本的蹦床来学习。 在哈斯克尔

  • GHC能否简化id=(\(a,b)- 更复杂的情况呢: GHC将简化映射到映射中? 我试图使用简单的beta缩减,但由于糟糕的模式匹配,这些术语看起来是不可缩减的。 因此,我很好奇GHC的优化技术如何处理这个问题。

  • 在Haskell中,下面的代码打印“[1,2,3,4,5”: 但是在Frege中,它抛出,代码如下: 这里唯一的区别是函数,它是从转换为和FWIW,函数是热切的。为什么整个表达式不能像Haskell中那样懒惰呢?在这里有可能实现类似弗雷格哈斯克尔的东西吗?