4

J'essaie d'apprendre Prolog. Ce sont mes premiers pas avec cette langue. Comme exercice je veux écrire un programme qui peut reconnaître certaines mains de poker (Quinte flush, Four of a kind, Full house etc.).Représentation des cartes dans Prolog

Je cherche une bonne représentation de carte dans Prolog. Je dois avoir la possibilité de vérifier si une carte est plus grande que l'autre, si les cartes sont adaptées et ainsi de suite.

J'ai commencé avec le code:

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. 

Cela donne la possibilité mi vérifier si le rang A est plus grand que par exemple J.

Mais je ne sais pas comment représenter seule carte. Cette représentation devrait contenir le rang de carte et également costume. Il y a aussi un problème avec Ace parce que Ace a le rang 14 mais il peut aussi être 1 en straight.

Donc, ma question est de savoir comment représente les cartes si je veux faire des règles comme:

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

ou

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

Je suis sûr que ce genre de question simple si vous connaissez la langue , mais il n'est pas si facile de «changer» de pensée à partir de langages comme C ou python. :-)

Répondre

2

Vous pouvez représenter des cartes sous la forme Rank-Suite.

Afin de vérifier si les cartes proviennent de la même suite définir un prédicat:

same_suit(_-S, _-S). 

Vous pouvez utiliser ce prédicat pour vérifier si vous avez une chasse d'eau:

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

Pour détecter si vous avez une paire, deux paires, un brelan, une maison pleine, ou un brelan, vous pouvez simplement compter le nombre de paires dans la main et ensuite mapper le résultat au nom de la main.

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

Exemples d'utilisation:

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

Merci pour votre réponse! Encore une fois, j'ai besoin de l'analyser. :) – Adam

2

Utilisez une liste de paires, card(rank, suite) pour la main. Définissez les prédicats pour compter le nombre de fois que chaque rang est répété dans une main, triez inversement en comptant, et vous avez le poker en [4,1], plein en [3,2], en trio en [3|_], etc. Un peu plus de travail avec le tri et le comptage révélera les couleurs et droites. Au lieu de valeurs numériques, utilisez les relations higher(a,b) et equal(a,b) qui s'appliquent aux deux rangs et aux mains (et aux combinaisons, si cette règle s'applique). Comme il n'y a que cinq cartes dans une main, vous pouvez vous en débarrasser en énumérant les possibilités au lieu de trier ... votre choix.

Remarque: J'ai supprimé les exemples de code car ils contenaient trop d'erreurs de syntaxe et de logique.

+0

Merci pour votre réponse. J'ai besoin de temps pour y penser. Je reviens avec des questions. ;) – Adam

+0

-1. Ce code est assez bogué (minuscules 'r' et 's'; 1 + compte), avez-vous réellement exécuté? – Kaarel

+0

@Kaarel Ça fait longtemps que je n'ai pas programmé en Prolog. Merci d'avoir signalé les erreurs. Je vais essayer de corriger le code. – Apalala

10

Vous pouvez utiliser unicode et SWI pour faire des programmes jolis ...

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

☝ ... ✓ (c'est génial!) – sharky

+0

Merci, bon à savoir. Mais je pense que je resterai avec les lettres traditionnelles. – Adam

+0

C'est vraiment cool, et très prologue! – Apalala