2011-12-13 5 views
1

J'essaie d'écrire un prédicat pour analyser les mains de poker courantes; par exemple donné une liste de "cartes" identifier si le joueur a 4 d'un genre; 3 d'un genre; paire etc: Mon idée était de vérifier le même rang et supprimer si non:Poker Main dans Prolog

cela fonctionne pour fourofakind (["A", "J", 10, "Q", "A", "A", " A "])

mais pas tous les scénarios; des conseils sur la logique ici?

Merci

+0

ces parenthèses sont si proches qu'elles semblent vertes sur mon moniteur. Je pensais que nous avions fait disparaître avec lisp :) –

+0

Voir aussi cette réponse http://stackoverflow.com/a/4674095/12547 – Kaarel

Répondre

1

Comme ACCS a souligné et d'avoir à nouveau le débat que nous avons eu à this post, vous pouvez utiliser append pour analyser avec succès votre liste une fois triés assez facilement. Sans le tri, vous pouvez écrire:

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

Cela dit essentiellement Prolog: Je veux ma main pour avoir 4 fois la sous-liste [X] avec quoi que ce soit entre les deux.

Ou, pour utiliser ce @false décrit comme très graphique solution attrayante dans his reply sur l'autre fil (DCG):

four --> ..., [X], ..., [X], ..., [X], ..., [X], ... . 

... --> [] | [_], ... . 

?- Xs = "bacada", phrase(four, Xs). 

Vous pouvez aussi éviter d'utiliser trop de Encastrements en faisant le travail avec base récursion:

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

Notez que ici one/2 équivaut à la définition naïve de member/2. Je vous laisse la tâche d'ajouter four_of_a_kind/1 en regardant comment three_of_a_kind/1 et pair/2 de travail! L'utilisation de la coupe serait également intéressante pour supprimer les points de choix inutilisés.

+0

'append/2' n'est pas disponible dans tous les systèmes Prolog et l'OP n'a pas spécifié s'il utilisait SWI. – twinterer

+0

vrai, si 'append/2' n'est pas disponible, la solution msort est beaucoup plus lisible donc j'irais avec ça je suppose (si vous voulez utiliser append ofc!). – m09

+0

Merci j'aime cette approche qui facilite tout ce dont j'ai besoin. J'ai vraiment besoin de me familiariser avec les builtin – Androider

3

Le problème est que vous vérifiez que si la première carte dans la main apparaît quatre fois dans l'ensemble. Vous devrez faire cela pour toutes les cartes.

J'introduirait un prédicat auxiliaire qui compte le nombre de cartes que vous avez vu, et que le principal itérer sous-jacente sur les cartes dans la main jusqu'à ce que vous avez trouvé un ensemble de quatre:

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 

Si ce n'était pas pour les listes courtes que vous pourriez l'améliorer, par exemple en vous souvenant des cartes que vous avez déjà vérifiées ou en les supprimant. Ce serait aussi beaucoup plus facile si la liste était triée pour commencer.

BTW, vous pouvez simplifier la liste imbriquée dans votre première clause d'origine comme [H,H,H,H] et dans la deuxième clause comme [H1,H2|T]. C'est plus facile pour les yeux!

+0

Merci, cela aide beaucoup. Mon but est de devenir plus fort dans ma pensée récursive et votre solution m'aide juste à ça! – Androider

2

Il faudrait envisager de mettre à profit les builtins: lorsque vous triez une liste de tous les éléments se regrouper, puis de vérifier une séquence devient facile:

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

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

Le prédicat a 2 formes, ce dernier prévoit également la carte code. S'il vous plaît utiliser le msort appel: en utilisant sorte que nous perdons des doublons ...

+0

Merci, je vois que je dois me familiariser avec les prédicats intégrés. – Androider