Presenting Maps in Prolog

I am trying to learn Prolog. These are my first steps with this language. As an exercise, I want to write a program that can recognize some poker hands (direct flush, four types, full house, etc.).

I am looking for a good representation in Prolog. I need to be able to check if there is more to one card than the other, if the cards fit and so one.

I started with the 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. 

This makes it possible to check whether rank A is greater than, for example, J.

But I'm not sure how to present one card. This view should contain the rank of the card as well as the suit. There is also a problem with Ace, because Ace has a rank of 14, but it can also be 1 in a straight line.

So my question is how to present maps if I want to make rules like:

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

or

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

I am sure this is a simple question if you know the language, but it’s not so easy to “switch” thinking from languages ​​like C or python. :-)

+4
source share
3 answers

You can submit cards in terms of a Rank-Suite form.

To check if cards fall from the same set, define a predicate:

 same_suit(_-S, _-S). 

You can use this predicate to check for a flush:

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

To determine if you have a pair, two pairs, three species, a full house or four, you can simply count the number of pairs in your hand and then compare the result with the name of the hand.

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

Examples of using:

 ?- count_pairs([qc, qd, qs, js, qh], PairsCount), pairs_hand(PairsCount, Hand). PairsCount = 6, Hand = four_of_a_kind. ?- count_pairs([jc, qd, qs, js, qh], PairsCount), pairs_hand(PairsCount, Hand). PairsCount = 4, Hand = full_house. ?- count_pairs([jc, qd, qs, js, 7-h], PairsCount), pairs_hand(PairsCount, Hand). PairsCount = 2, Hand = two_pair. 
+2
source

You can use unicode and SWI to create good programs ...

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

Use the list of pairs, card(rank, suite) for the hand. Define predicates for counting the number of times each rank is repeated in the hand, sort back by the score, and you have poker in [4,1] , full [3,2] , trio in [3|_] , etc. A little more work with sorting and counting will show flushes and straights. Instead of numerical values, use the higher(a,b) and equal(a,b) ratios that apply to both ranks and hands (and suits if this rule applies).

Since there are only five cards in hand, you can leave with a list of options instead of sorting ... of your choice.

Note. I deleted the code samples because they contained too many syntax and logical errors.

+2
source

Source: https://habr.com/ru/post/1335297/


All Articles