2011-12-13 71 views
1

我想写一个谓词来分析普通扑克牌手;例如给出一张“卡片”列表来标识玩家是否有4种类型;一种3;对等: 我的想法是检查相似的等级,如果不是,则删除:扑克之手Prolog

这适用于fourofakind([A,J,10,Q,A, A“])

但不是所有情况;这里有关逻辑的任何指导?

感谢

+0

这些支架非常接近,它们在我的显示器上看起来很绿。我认为我们已经用lisp完成了这个工作:) –

+0

另请参阅此答案http://stackoverflow.com/a/4674095/12547 – Kaarel

回答

1

由于CHAC指出,并再次有我们this post有争论,你可以使用附加成功地解析您的列表排序一次很容易。如果没有排序,你可以写:

fourofakind(Hand, X) :- append([_, [X], _, [X], _, [X], _, [X], _], Hand). 

这主要是告诉序言:我想我的手有子列表4倍[X]与任何在两者之间。

或者使用什么@false描述为his reply其他线程(DCG中)在一个非常图形化等吸引人的解决方案:

four --> ..., [X], ..., [X], ..., [X], ..., [X], ... . 

... --> [] | [_], ... . 

?- Xs = "bacada", phrase(four, Xs). 

你可能也避免做的工作基本使用过多的内置插件递归:

three_of_a_kind(Item, [Item|Tail]) :- pair(Item, Tail). 
three_of_a_kind(Item, [_Item|Tail]) :- three_of_a_kind(Item, Tail). 

pair(Item, [Item|Tail]) :- one(Item, Tail). 
pair(Item, [_NotItem|Tail]) :- pair(Item, Tail). 

one(Item, [Item|_Tail]). 
one(Item, [_NotItem|Tail]) :- one(Item, Tail). 

注意的是,这里one/2相当于member/2天真的定义。我通过查看three_of_a_kind/1pair/2的工作方式,让您加入four_of_a_kind/1的任务!删除未使用的选择点也会很有趣。

+0

'append/2'在所有的Prolog系统中都不可用,并且OP没有指定他是否使用SWI。 – twinterer

+0

是真的,如果'append/2'不可用,msort解决方案更具可读性,所以我认为(如果想使用append ofc!)。 – m09

+0

谢谢,我喜欢这种方法有利于我所需要的一切。我绝对需要更熟悉内置的 – Androider

3

的问题是,你只检查手中的第一张牌是否出现在集合四倍。您需要为所有卡片做到这一点。

我会介绍计数的,你所看到的卡的数量的辅助谓词,并让在手中的卡主谓迭代,直到你发现了一组四:

four([H|T]) :- four0(H,1,T), !. % find a set of four Hs 
four([_|T]) :- four(T).   % else continue with remaining set 

four0(_,4,_) :- !.        % found four cards: stop 
four0(X,I,[X|T]) :- !,I1 is I+1,four0(X,I1,T). % found another card: inc counter 
four0(X,I,[_|T]) :- four0(X,I,T).    % else continue 

如果并不是因为短名单可以改进它,例如,记住已经检查或删除了哪些卡。如果清单是从一开始就排序的,那么它也会容易得多。

顺便说一下,您可以简化原始第一个子句中的嵌套列表[H,H,H,H],并在第二个子句中将其简化为[H1,H2|T]。在眼睛上更容易!

+0

谢谢,这有助于很多。我的目标是在递归思想中变得更强大,您的解决方案可以帮助我! – Androider

2

考虑到善加利用内建的:当你排序列表中的所有元素,会进行分组,然后检查序列变得容易:

fourofakind(Hand) :- % not intersted to what card is 
fourofakind(Hand, _). 

fourofakind(Hand, C) :- 
msort(Hand, Sorted), 
append([_, [C,C,C,C], _], Sorted). 

谓词有2种形式,后者还提供了卡码。请使用msort电话:使用排序,我们失去了重复...

+0

谢谢,我看到我需要更熟悉内建的谓词。 – Androider