首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Prolog中的卡片表示

Prolog中的卡片表示
EN

Stack Overflow用户
提问于 2011-01-13 03:25:40
回答 3查看 2.1K关注 0票数 5

我在试着学习Prolog。这是我使用这门语言的第一步。作为练习,我想写一个程序,它可以识别一些扑克牌手(直同花顺,四种,满屋等)。

我正在寻找好的Prolog卡片表示法。我需要有可能检查是否一张卡比其他的更大,如果卡是合适的,等等。

我已经从代码开始了:

代码语言:javascript
运行
复制
rank(2).
rank(3).
rank(4).
rank(5).
rank(6).
rank(7).
rank(8).
rank(9).
rank(t).
rank(j).
rank(q).
rank(k).
rank(a).

value(2, 2).
value(3, 3).
value(4, 4).
value(5, 5).
value(6, 6).
value(7, 7).
value(8, 8).
value(9, 9).
value(t, 10).
value(j, 11).
value(q, 12).
value(k, 13).
value(a, 14).
%value(a, 1).

suite(d).
suite(h).
suite(c).
suite(s).

rank_bigger(X, Y) :-
               value(X, A),
               value(Y, B),
               A > B.

这给了mi检查秩A是否大于例如J的可能性。

但我不确定如何表示单张卡片。此表示应包含牌的等级和花色。Ace也有一些问题,因为Ace的排名是14,但它也可以是1。

所以我的问题是,如果我想制定如下规则,如何表示卡片:

代码语言:javascript
运行
复制
isStraight(C1, C2, C3, C4, C5) :- 
                                  [...]

代码语言:javascript
运行
复制
isStraightFlush(C1, C2, C3, C4, C5) :- 
                                       [...]

我敢肯定,如果你懂语言,这是一个很简单的问题,但要从C或python这样的语言中“切换”思维并不是那么容易。:-)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-01-13 05:08:24

您可以用Rank-Suite形式将卡片表示为术语。

为了检查这些卡片是否来自同一个套件,请定义一个谓词:

代码语言:javascript
运行
复制
same_suit(_-S, _-S).

您可以使用此谓词来检查是否有刷新:

代码语言:javascript
运行
复制
?- Cards = [1-d, 2-d, 3-d, 4-d, 5-d], maplist(same_suit(_-S), Cards).
Cards = [1-d, 2-d, 3-d, 4-d, 5-d],
S = d.

为了检测你是否有一对、两对、三对、满屋或四对,你只需数一数手中的对数,然后将结果映射到手的名称。

代码语言:javascript
运行
复制
% Count the number of pairs in the given list of cards.
count_pairs([], 0).

count_pairs([R-_ | Cs], Pairs) :-
    count_rank(R, Cs, RankCount),
    count_pairs(Cs, Pairs0),
    Pairs is RankCount + Pairs0.


% Count the number of cards with the given rank
count_rank(R, Cs, RankCount) :-
    count_rank(R, Cs, 0, RankCount).


count_rank(_, [], RankCount, RankCount) :- !.

count_rank(R, [R-_ | Cs], RankCount0, RankCount) :-
    !,
    RankCount1 is RankCount0 + 1,
    count_rank(R, Cs, RankCount1, RankCount).

count_rank(R, [_ | Cs], RankCount0, RankCount) :-
    count_rank(R, Cs, RankCount0, RankCount).


% Map the number of pairs to the name of the hand
pairs_hand(1, one_pair).
pairs_hand(2, two_pair).
pairs_hand(3, three_of_a_kind).
pairs_hand(4, full_house).
%pairs_hand(5, 'NOT POSSIBLE').
pairs_hand(6, four_of_a_kind).

使用示例:

代码语言:javascript
运行
复制
?- count_pairs([q-c, q-d, q-s, j-s, q-h], PairsCount), pairs_hand(PairsCount, Hand).
PairsCount = 6,
Hand = four_of_a_kind.

?- count_pairs([j-c, q-d, q-s, j-s, q-h], PairsCount), pairs_hand(PairsCount, Hand).
PairsCount = 4,
Hand = full_house.

?- count_pairs([j-c, q-d, q-s, j-s, 7-h], PairsCount), pairs_hand(PairsCount, Hand).
PairsCount = 2,
Hand = two_pair.
票数 2
EN

Stack Overflow用户

发布于 2011-01-13 09:26:33

你可以使用unicode和SWI来制作漂亮的程序...

代码语言:javascript
运行
复制
:- op(200, xf, ♥).
:- op(200, xf, ♦).
:- op(200, xf, ♣).
:- op(200, xf, ♠).
:- op(200, xf, ♡).
:- op(200, xf, ♢).
:- op(200, xf, ♧).
:- op(200, xf, ♤).

main :- print([2♠,3♦,'K'♥,10♠,3♣]),
        isFlush(2♠,3♦,'K'♥,10♠,3♣).

isFlush(♥(_),♥(_),♥(_),♥(_),♥(_)).
isFlush(♦(_),♦(_),♦(_),♦(_),♦(_)).
isFlush(♣(_),♣(_),♣(_),♣(_),♣(_)).
isFlush(♠(_),♠(_),♠(_),♠(_),♠(_)).
票数 10
EN

Stack Overflow用户

发布于 2011-01-13 03:50:20

使用配对列表,card(rank, suite)表示手。定义谓词来计算每个等级在一只手中重复的次数,按计数进行反向排序,这样你就有了[4,1]中的poker,[3,2]中的full,[3|_]中的trio,等等。使用关系higher(a,b)equal(a,b)代替数字值,这两个关系既适用于职级,也适用于手(如果规则适用,还适用于西装)。

因为一手中只有五张牌,所以您可以列举可能性而不是排序……你自己选吧。

注意:我删除了代码示例,因为它们包含太多的语法和逻辑错误。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4673076

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档