- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 working implementation的Kalah求解器,一个计算游戏第一回合的最佳连续移动的应用程序。
我正在重新实现这个应用程序,尽管这次使用了测试套件和(希望)更漂亮的代码,利用了更有趣的结构,如幺半群或单子(monad)。
正如您在 original code 中看到的那样(或者不是,它非常复杂,这就是我重写它的原因)我定义了一个“移动”如下:
Pot
列表作为我的棋盘,以及我这边棋盘的起始位置。Pot
列表的末尾。[Pot]
)、我手中可能持有多少颗弹珠以及表示我是否应该再跑一圈的 ADT或不(LapResult
)。问题是,我怀疑如果我用一些巧妙的数据结构来表达棋盘状态,我就不需要将移动分成几圈,我既可以将其作为函数的输入参数传递并拥有相同的数据结构作为返回值出现。至少这是我的猜测,我的想法是董事会状态让我想起了我读过的有关幺半群的内容。
因此,如果我将一个“移动”定义为所有拾取和掉落的弹珠,直到您落在空 jar 或商店中,是否有一些明显的方法可以重写“移动”的代码有效吗?
可以找到重新实现的当前状态 here .
最佳答案
注意:我还没有测试过这些。它可能有问题。
我认为你的问题是你需要从两个角度来考虑董事会,称它们为“白”和“黑”。
data Player = White | Black
otherPlayer :: Player -> Player
otherPlayer White = Black
otherPlayer Black = White
Mancala 板是一个循环结构,这表明模块化运算。我建议类似:
import Data.Vector -- More efficient version of Array
type PotNum = Int -- Use Int for simple index of pot position.
type Pot = Int -- Just record number of marbles in the pot.
通过使用 Data.Word8 而不是 Int,您可能会获得更紧凑的数据结构,但我不确定。暂时保持简单。
type Board = Vector Pot
然后让 isStore 成为 PotNum 和播放器的简单函数
isStore :: Player -> PotNum -> Bool
isStore White 0 = True
isStore Black 7 = True
isStore _ _ = False
您还想在棋盘上向前移动,跳过其他玩家的商店..
nextPot :: Player -> PotNum -> PotNum
nextPot White 6 = 8 -- Skip Black's store
nextPot White 13 = 0
nextPot Black 12 = 0 -- Skip White's store
nextPot _ n = n + 1
每个玩家控制的底池列表
playerPots :: Player -> [PotNum] -- Implementation omitted.
给定 jar 中的弹珠数量
marblesIn :: PotNum -> Board -> Int -- Implementation omitted.
现在您可以编写移动函数了。对于非法移动,我们将让它返回 Nothing。
move :: Player -> PotNum -> Board -> Maybe Board -- Implementation omitted.
使用 List monad,您可以使其产生所有潜在的移动和结果板状态
allMoves :: Player -> Board -> [(PotNum, Board)]
allMoves p b1 = do
n <- playerPots p
case move p n b1 of
Nothing -> fail "" -- List monad has this as []
Just b2 -> return (n, b2)
现在您可以使用 Data.Tree.unfold 从任何起始位置获取完整的游戏树,它采用 move 函数的变体。这有点不优雅;我们想知道导致该位置的移动,但初始位置没有导致该位置的移动。因此,也许。
unfoldTree 函数采用一个函数(下面代码中的 f),该函数采用当前状态并返回当前节点和子节点值列表。当前状态和当前节点都是刚刚移动的玩家、他们所做的移动以及结果棋盘的三重关系。因此是“f”的第一位。 “f”的第二位调用“opponentMoves”函数,该函数转换“allMoves”返回的值以添加正确的数据。
unfoldGame :: Player -> Board -> Tree (Player, Maybe PotNum, Board)
unfoldGame p b = unfoldTree f (p, Nothing, b)
where
f (p1, n1, b1) = ((p1, n1, b1), opponentMoves (otherPlayer p1), b1
opponentMoves p2 b2 = map (\(n3, b3) -> (p2, Just n3, b3)) $ allMoves p2 b2
现在你只需要走树即可。每一片叶子都是游戏的结束,因为没有剩下合法的 Action 。 ExpandGame 函数是惰性函数,因此您只需要内存来保存当前正在考虑的游戏状态。
关于haskell - 我应该使用什么结构来表达棋盘游戏中的回合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19617427/
我想做的是让 JTextPane 在 JPanel 中占用尽可能多的空间。对于我使用的 UpdateInfoPanel: public class UpdateInfoPanel extends JP
我在 JPanel 中有一个 JTextArea,我想将其与 JScrollPane 一起使用。我正在使用 GridBagLayout。当我运行它时,框架似乎为 JScrollPane 腾出了空间,但
我想在 xcode 中实现以下功能。 我有一个 View Controller 。在这个 UIViewController 中,我有一个 UITabBar。它们下面是一个 UIView。将 UITab
有谁知道Firebird 2.5有没有类似于SQL中“STUFF”函数的功能? 我有一个包含父用户记录的表,另一个表包含与父相关的子用户记录。我希望能够提取用户拥有的“ROLES”的逗号分隔字符串,而
我想使用 JSON 作为 mirth channel 的输入和输出,例如详细信息保存在数据库中或创建 HL7 消息。 简而言之,输入为 JSON 解析它并输出为任何格式。 最佳答案 var objec
通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何一台计算机都无法处理它! (任何从事遗传学工作的人的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,我只剩
我有一个以前可能被问过的问题,但我很难找到正确的描述。我希望有人能帮助我。 在下面的代码中,我设置了varprice,我想添加javascript变量accu_id以通过rails在我的数据库中查找记
我有一个简单的 SVG 文件,在 Firefox 中可以正常查看 - 它的一些包装文本使用 foreignObject 包含一些 HTML - 文本包装在 div 中:
所以我正在为学校编写一个 Ruby 程序,如果某个值是 1 或 3,则将 bool 值更改为 true,如果是 0 或 2,则更改为 false。由于我有 Java 背景,所以我认为这段代码应该有效:
我做了什么: 我在这些账户之间创建了 VPC 对等连接 互联网网关也连接到每个 VPC 还配置了路由表(以允许来自双方的流量) 情况1: 当这两个 VPC 在同一个账户中时,我成功测试了从另一个 La
我有一个名为 contacts 的表: user_id contact_id 10294 10295 10294 10293 10293 10294 102
我正在使用 Magento 中的新模板。为避免重复代码,我想为每个产品预览使用相同的子模板。 特别是我做了这样一个展示: $products = Mage::getModel('catalog/pro
“for”是否总是检查协议(protocol)中定义的每个函数中第一个参数的类型? 编辑(改写): 当协议(protocol)方法只有一个参数时,根据该单个参数的类型(直接或任意)找到实现。当协议(p
我想从我的 PHP 代码中调用 JavaScript 函数。我通过使用以下方法实现了这一点: echo ' drawChart($id); '; 这工作正常,但我想从我的 PHP 代码中获取数据,我使
这个问题已经有答案了: Event binding on dynamically created elements? (23 个回答) 已关闭 5 年前。 我有一个动态表单,我想在其中附加一些其他 h
我正在尝试找到一种解决方案,以在 componentDidMount 中的映射项上使用 setState。 我正在使用 GraphQL连同 Gatsby返回许多 data 项目,但要求在特定的 pat
我在 ScrollView 中有一个 View 。只要用户按住该 View ,我想每 80 毫秒调用一次方法。这是我已经实现的: final Runnable vibrate = new Runnab
我用 jni 开发了一个 android 应用程序。我在 GetStringUTFChars 的 dvmDecodeIndirectRef 中得到了一个 dvmabort。我只中止了一次。 为什么会这
当我到达我的 Activity 时,我调用 FragmentPagerAdapter 来处理我的不同选项卡。在我的一个选项卡中,我想显示一个 RecyclerView,但他从未出现过,有了断点,我看到
当我按下 Activity 中的按钮时,会弹出一个 DialogFragment。在对话框 fragment 中,有一个看起来像普通 ListView 的 RecyclerView。 我想要的行为是当
我是一名优秀的程序员,十分优秀!