質問

私はプロログを学ぼうとしています。これは、この言語での私の最初のステップです。エクササイズとして、ポーカーハンドを認識できるプログラム(ストレートフラッシュ、4つの種類のフルハウスなど)を作成したいと思います。

Prologの良いカード表現を探しています。 1枚のカードが他のカードよりも大きいかどうか、カードが適しているかどうかを確認する必要があります。

私はコードから始めました:

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.

これにより、ランクAがJよりも大きいかどうかを確認するMIが可能になります。

しかし、シングルカードを表現する方法がわかりません。この表現には、カードのランクとスーツが含まれている必要があります。 ACEにはランク14があるため、ACEにはいくつかの問題がありますが、ストレートでも1つになる可能性があります。

ですから、私の質問は、次のようなルールを作成したい場合、カードを表す方法です。

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

また

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

言語を知っているなら、これは一種の簡単な質問だと確信していますが、CやPythonなどの言語から考えることを「切り替える」のはそれほど簡単ではありません。 :-)

役に立ちましたか?

解決

フォームの用語としてカードを表すことができます 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.

ペア、2つのペア、3つの種類、フルハウス、または4種類の種類があるかどうかを検出するために、数を数えることができます ペア 手で、結果を手の名前にマッピングします。

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

他のヒント

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

ペアのリストを使用して、 card(rank, suite) 手のために。各ランクが手で繰り返される回数をカウントするように述べられた述語を定義し、カウントによって逆にソートすると、ポーカーがあります [4,1], 、フルイン [3,2], 、トリオイン [3|_], 、など。並べ替えとカウントのもう少し作業では、フラッシュとストレートが明らかになります。数値値の代わりに、関係を使用します higher(a,b)equal(a,b) それはランクと手に適用されます(およびそのルールが適用される場合)。

手には5枚のカードしかないので、ソートする代わりに可能性を列挙することで逃げることができます...あなたの選択。

注:コードサンプルには、構文とロジックエラーが多すぎたため、コードサンプルが削除されました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top