序言中的卡片表示

问题描述 投票:5回答:3

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

我正在Prolog中寻找良好的卡代表。我需要检查一张卡是否大于另一张,是否适合,等等。

我已经开始使用代码:

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位。

所以我的问题是,如果我想制定类似规则,该如何代表卡片:

isStraight(C1, C2, C3, C4, C5) :- 
                                  [...]

isStraightFlush(C1, C2, C3, C4, C5) :- 
                                       [...]

如果您知道语言,我敢肯定这是一个简单的问题,但是要想从C或python等语言“转换”思维并不是那么容易。 :-)

prolog poker
3个回答
2
投票

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

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

same_suit(_-S, _-S).

您可以使用此谓词检查是否有同花顺:

?- 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.

为了检测您是否有一对,两对,三个同类,满屋或四个同类,您只需要数一数pairs的数量,然后将结果映射到手名。

% 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).

用法示例:

?- 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.

10
投票

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

:- 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(♠(_),♠(_),♠(_),♠(_),♠(_)).

2
投票

使用成对清单,手为card(rank, suite)。定义谓词以计算手中的每个等级重复出现的次数,并按计数进行反向排序,然后在[4,1]中有扑克,在[3,2]中有扑克,在[3|_]中有三重奏,等等。计数将显示出同花顺和顺直。代替数值,使用关系higher(a,b)equal(a,b)既适用于等级,也适用于双手(如果适用该规则,则适用于西装)。

由于手中只有五张牌,因此您可以列举各种可能性,而不必进行排序...选择。

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

© www.soinside.com 2019 - 2024. All rights reserved.