Покер Хэнд в Прологе - PullRequest
       9

Покер Хэнд в Прологе

1 голос
/ 13 декабря 2011

Я пытаюсь написать предикат для анализа общих покерных комбинаций; например, учитывая список «карт», укажите, есть ли у игрока 4 вида; 3 вида; пара и т. д. Моя идея состояла в том, чтобы проверить на подобный ранг и удалить, если нет:

это работает для четвероногих (["A", "J", 10, "Q", "A", "A", "A"])

но не все сценарии; Любое руководство по логике здесь?

Спасибо

Ответы [ 3 ]

3 голосов
/ 13 декабря 2011

Проблема в том, что вы только проверяете, появляется ли первая карта в руке четыре раза в наборе. Это необходимо сделать для всех карт.

Я хотел бы ввести вспомогательный предикат, который подсчитывает количество карт, которые вы видели, и позволить основному предикату перебирать карты в руке, пока вы не найдете набор из четырех:

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]. Это проще для глаз!

2 голосов
/ 13 декабря 2011

Рекомендуется использовать встроенные функции: когда вы сортируете список, все элементы группируются, тогда проверка последовательности упрощается:

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

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

Предикат имеет 2 формы, последний также предоставляет код карты. Пожалуйста, используйте вызов msort : используя сортировку, мы теряем дубликаты ...

1 голос
/ 13 декабря 2011

Как указал Чак, и чтобы снова начать обсуждение, которое мы провели в этом посте , вы можете использовать команду append, чтобы успешно разобрать ваш список, как только он будет отсортирован довольно легко.Без сортировки вы могли бы написать:

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

Это в основном говорит прологу: я хочу, чтобы у моей руки был 4-кратный подсписок [X] с чем-то промежуточным.

Или использоватьчто @ false описывает как очень графически привлекательное решение в его ответе в другом потоке (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.Я дал вам задачу добавить four_of_a_kind/1, посмотрев, как работают three_of_a_kind/1 и pair/2!Было бы интересно использовать вырезание, чтобы убрать неиспользованные точки выбора.

...