Prolog 中的扑克牌
我正在尝试编写一个谓词来分析常见的扑克牌;例如,给定一个“牌”列表,确定玩家是否有 4 张同种牌; 3 个;对等: 我的想法是检查相似的排名,如果没有则删除:
这适用于 fourofakind(["A","J",10,"Q","A","A","A"])
但不适用于所有情况;这里的逻辑有什么指导吗?
谢谢
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问题是你只检查手中的第一张牌是否在该组中出现了四次。您需要对所有卡执行此操作。
我会引入一个辅助谓词来计算您已经看到的牌的数量,并让主要谓词迭代手上的牌,直到找到一组四张牌:
如果不是短列表,您可以改进它例如,记住您已经检查过哪些卡片或删除它们。如果一开始就对列表进行排序,也会容易得多。
顺便说一句,您可以将原始第一个子句中的嵌套列表简化为
[H,H,H,H]
,将第二个子句中的嵌套列表简化为[H1,H2|T]
>。这样眼睛就更容易了!The problem is that you only check whether the first card in the hand appears four times in the set. You will need to do that for all cards.
I would introduce an auxiliary predicate that counts the number of cards you have seen, and let the main predicate iterate over the cards in the hand until you've found a set of four:
If it wasn't for short lists you could improve it by, e.g., remembering what cards you already checked or removing them. It also would be much easier if the list was sorted to begin with.
BTW, you can simplify the nested list in your original first clause as
[H,H,H,H]
, and in the second clause as[H1,H2|T]
. It's easier on the eyes!考虑充分利用内置函数:当您对列表进行排序时,所有元素都会分组,然后检查序列变得很容易:
谓词有 2 种形式,后者还提供卡片代码。请使用msort调用:使用排序我们会丢失重复项...
Consider to put to good use the builtins: when you sort a list all elements get grouped, then check for a sequence become easy:
The predicate has 2 forms, the latter also provides the card code. Please use the msort call: using sort we lose duplicates...
正如 chac 指出的那样,为了再次进行我们在 这篇文章 中进行的辩论,您可以成功使用追加一旦排序就很容易解析你的列表。如果没有排序,你可以写:
这基本上告诉序言:我希望我的手有 4 倍的子列表 [X] 以及中间的任何内容。
或者,使用 @false 在 他在另一个线程(DCG)上的回复:
您也可以通过使用基本递归来避免使用太多内置函数:
请注意,这里
one/2
相当于member/2
的简单定义。我让您通过查看two_of_a_kind/1
和pair/2
的工作原理来完成添加four_of_a_kind/1
的任务!使用 cut 来删除未使用的选择点也很有趣。As chac pointed out and to have again the debate we had in this post, you can use append to successfully parse your list once sorted quite easily. Without sorting, you could write :
This basically tells prolog : I want my hand to have 4 times the sublist [X] with anything in-between.
Or, to use what @false describes as a very graphically appealing solution in his reply on the other thread (DCGs) :
You could too avoid using too many built-ins by doing the work with basic recursion :
Note that here
one/2
is equivalent to the naive definition ofmember/2
. I let you the task of addingfour_of_a_kind/1
by looking at howthree_of_a_kind/1
andpair/2
work ! Use of cut would be interesting too to remove unused choice points.