Представление карт в Прологе - PullRequest
5 голосов
/ 12 января 2011

Я пытаюсь выучить пролог. Это мои первые шаги с этим языком. В качестве упражнения я хочу написать программу, которая распознает некоторые покерные руки (стрит-флеш, четверка, фулл-хаус и т. Д.).

Я ищу хорошее представление карты в Прологе. Мне нужно иметь возможность проверить, больше ли одна карта, чем другая, подходят ли карты и так далее.

Я начал с кода:

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.

Но я не уверен, как представлять одну карту. Это представление должно содержать ранг карты, а также масть. Есть также некоторая проблема с тузом, потому что у туза есть ранг 14, но он также может быть 1 в стрите.

Так что мой вопрос в том, как представлять карты, если я хочу создать такие правила, как:

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

или

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

Я уверен, что это довольно простой вопрос, если вы знаете язык, но не так просто «переключить» мышление с языков, таких как C или python. : -)

Ответы [ 3 ]

10 голосов
/ 13 января 2011

Вы можете использовать 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 голосов
/ 13 января 2011

Вы можете представлять карточки как термины с формой 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.

Чтобы определить, есть ли у вас пара, две пары, три вида, фулл-хаус или четыре типа, вы можете просто посчитать количество пар в руке и затем отобразить карту. результат к названию руки.

% 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.
2 голосов
/ 12 января 2011

Используйте список пар, card(rank, suite) для руки.Определите предикаты для подсчета количества раз, которое каждый ранг повторяется в руке, сортируйте обратно по количеству, и у вас есть покер в [4,1], полный в [3,2], трио в [3|_] и т.д.и подсчет покажет приливы и стриты.Вместо числовых значений используйте отношения higher(a,b) и equal(a,b), которые применяются как к рангу, так и к рукам (и к мастям, если применяется это правило).

Поскольку в руке всего пять карт, выможно сойти с перечисления возможностей вместо сортировки ... ваш выбор.

Примечание: я удалил примеры кода, потому что они содержали слишком много синтаксических и логических ошибок.

...