deck([[2,spades], [3,spades], [4,spades], [5,spades], [6,spades], [7,spades], [8,spades], [9,spades], [10,spades], ['J',spades], ['Q',spades], ['K',spades], ['A',spades], [2,clubs], [3,clubs], [4,clubs], [5,clubs], [6,clubs], [7,clubs], [8,clubs], [9,clubs], [10,clubs], ['J',clubs], ['Q',clubs], ['K',clubs], ['A',clubs], [2,hearts], [3,hearts], [4,hearts], [5,hearts], [6,hearts], [7,hearts], [8,hearts], [9,hearts], [10,hearts], ['J',hearts], ['Q',hearts], ['K',hearts], ['A',hearts], [2,diamonds], [3,diamonds], [4,diamonds], [5,diamonds], [6,diamonds], [7,diamonds], [8,diamonds], [9,diamonds], [10,diamonds], ['J',diamonds], ['Q',diamonds], ['K',diamonds], ['A',diamonds] ]). print_hand([]). print_hand([First|Rest]) :- length(Rest, 6), write('The two hole cards are ...'), nl, nl, print_card(First), nl, print_hand(Rest). print_hand([First|Rest]) :- length(Rest, 4), nl, write('The community cards are ...'), nl, nl, print_card(First), nl, print_hand(Rest). print_hand([First|Rest]) :- print_card(First), nl, print_hand(Rest). print_card([Val,Suit]) :- write(Val), write(' of '), write(Suit). split_hand([], [], []). split_hand([Card|Rest], [Cardhead|Cardrest], [Suithead|Suitrest]) :- split_card(Card, Cardhead, Suithead), split_hand(Rest, Cardrest, Suitrest). split_card([Card,Suit], Card, Suit). deal(_, [], Hand) :- length(Hand, 7). /* we have 7 cards */ deal(Deck, [Head|Rest], Sofar) :- Rand is random(52), nth0(Rand, Deck, Card), not(member(Card, Sofar)), Head = Card, append([Card], Sofar, Sofarupdated), deal(Deck, Rest, Sofarupdated). deal(Deck, List, Sofar) :- deal(Deck, List, Sofar). /* a card was repeated, so try again */ check_royalflush(Hand) :- member([10, X], Hand), member(['J', X], Hand), member(['Q', X], Hand), member(['K', X], Hand), member(['A', X], Hand), write('Royal flush of '), write(X), nl. check_straightflush(Hand) :- member(['A', X], Hand), member([2, X], Hand), member([3, X], Hand), member([4, X], Hand), member([5, X], Hand), print_straightflush(5, X). check_straightflush(Hand) :- member([2, X], Hand), member([3, X], Hand), member([4, X], Hand), member([5, X], Hand), member([6, X], Hand), print_straightflush(6, X). check_straightflush(Hand) :- member([3, X], Hand), member([4, X], Hand), member([5, X], Hand), member([6, X], Hand), member([7, X], Hand), print_straightflush(7, X). check_straightflush(Hand) :- member([4, X], Hand), member([5, X], Hand), member([6, X], Hand), member([7, X], Hand), member([8, X], Hand), print_straightflush(8, X). check_straightflush(Hand) :- member([5, X], Hand), member([6, X], Hand), member([7, X], Hand), member([8, X], Hand), member([9, X], Hand), print_straightflush(9, X). check_straightflush(Hand) :- member([6, X], Hand), member([7, X], Hand), member([8, X], Hand), member([9, X], Hand), member([10, X], Hand), print_straightflush(10, X). check_straightflush(Hand) :- member([7, X], Hand), member([8, X], Hand), member([9, X], Hand), member([10, X], Hand), member(['J', X], Hand), print_straightflush('J', X). check_straightflush(Hand) :- member([8, X], Hand), member([9, X], Hand), member([10, X], Hand), member(['J', X], Hand), member(['Q', X], Hand), print_straightflush('Q', X). check_straightflush(Hand) :- member([9, X], Hand), member([10, X], Hand), member(['J', X], Hand), member(['Q', X], Hand), member(['K', X], Hand), print_straightflush('K', X). check_straightflush(Hand) :- member([10, X], Hand), member(['J', X], Hand), member(['Q', X], Hand), member(['K', X], Hand), member(['A', X], Hand), print_straightflush('A', X). print_straightflush(Highcard, Suit) :- write(Highcard), write(' high straight flush of '), write(Suit), nl. check_four([X,X,X,X,_,_,_]) :- is_four(X). check_four([_,X,X,X,X,_,_]) :- is_four(X). check_four([_,_,X,X,X,X,_]) :- is_four(X). check_four([_,_,_,X,X,X,X]) :- is_four(X). is_four(Card) :- write('Four '), write(Card), write('s'), nl. /* we have to describe the case where we have 2 sets of three so that we can pick the better for the set of 3 */ check_fullhouse([X,X,X,Y,Y,Y,_], _) :- is_fullhouse(X, Y). check_fullhouse([X,X,X,_,Y,Y,Y], _) :- is_fullhouse(X, Y). check_fullhouse([_,X,X,X,Y,Y,Y], _) :- is_fullhouse(X, Y). check_fullhouse(_, Hand) :- member([X, A], Hand), member([X, B], Hand), member([X, C], Hand), member([Y, D], Hand), member([Y, E], Hand), not(A = B), not(A = C), not(B = C), not(D = E), not(X = Y), print_fullhouse(X,Y). is_fullhouse(X, Y) :- X = 'A', print_fullhouse(X, Y). is_fullhouse(X, Y) :- Y = 'A', print_fullhouse(Y, X). is_fullhouse(X, Y) :- X = 'K', print_fullhouse(X, Y). is_fullhouse(X, Y) :- Y = 'K', print_fullhouse(Y, X). is_fullhouse(X, Y) :- X = 'Q', print_fullhouse(X, Y). is_fullhouse(X, Y) :- Y = 'Q', print_fullhouse(Y, X). is_fullhouse(X, Y) :- X = 'J', print_fullhouse(X, Y). is_fullhouse(X, Y) :- Y = 'J', print_fullhouse(Y, X). is_fullhouse(X, Y) :- X > Y, print_fullhouse(X, Y). is_fullhouse(X, Y) :- Y > X, print_fullhouse(Y, X). print_fullhouse(X, Y) :- write('Full House - '), write(X), write('s full of '), write(Y), write('s'), nl. check_flush([X,X,X,X,X,_,_]) :- print_flush(X). check_flush([_,X,X,X,X,X,_]) :- print_flush(X). check_flush([_,_,X,X,X,X,X]) :- print_flush(X). print_flush(Suit) :- write('Flush of '), write(Suit), nl. check_straight(Hand) :- member(['A', _], Hand), member([2, _], Hand), member([3, _], Hand), member([4, _], Hand), member([5, _], Hand), print_straight(5). check_straight(Hand) :- member([2, _], Hand), member([3, _], Hand), member([4, _], Hand), member([5, _], Hand), member([6, _], Hand), print_straight(6). check_straight(Hand) :- member([3, _], Hand), member([4, _], Hand), member([5, _], Hand), member([6, _], Hand), member([7, _], Hand), print_straight(7). check_straight(Hand) :- member([4, _], Hand), member([5, _], Hand), member([6, _], Hand), member([7, _], Hand), member([8, _], Hand), print_straight(8). check_straight(Hand) :- member([5, _], Hand), member([6, _], Hand), member([7, _], Hand), member([8, _], Hand), member([9, _], Hand), print_straight(9). check_straight(Hand) :- member([6, _], Hand), member([7, _], Hand), member([8, _], Hand), member([9, _], Hand), member([10, _], Hand), print_straight(10). check_straight(Hand) :- member([7, _], Hand), member([8, _], Hand), member([9, _], Hand), member([10, _], Hand), member(['J', _], Hand), print_straight('J'). check_straight(Hand) :- member([8, _], Hand), member([9, _], Hand), member([10, _], Hand), member(['J', _], Hand), member(['Q', _], Hand), print_straight('Q'). check_straight(Hand) :- member([9, _], Hand), member([10, _], Hand), member(['J', _], Hand), member(['Q', _], Hand), member(['K', _], Hand), print_straight('K'). check_straight(Hand) :- member([10, _], Hand), member(['J', _], Hand), member(['Q', _], Hand), member(['K', _], Hand), member(['A', _], Hand), print_straight('A'). print_straight(Highcard) :- write(Highcard), write(' high straight'), nl. check_three(Hand) :- member([X, A], Hand), member([X, B], Hand), member([X, C], Hand), not(A = B), not(A = C), not(B = C), write('Three '), write(X), write('s'), nl. /* We have to describe the case where there are three sets of 2 so we can pick the best 2 pair */ check_twopair([X,X,Y,Y,Z,Z,_], _) :- three_pairs(X, Y, Z). check_twopair([X,X,Y,Y,_,Z,Z], _) :- three_pairs(X, Y, Z). check_twopair([X,X,_,Y,Y,Z,Z], _) :- three_pairs(X, Y, Z). check_twopair([_,X,X,Y,Y,Z,Z], _) :- three_pairs(X, Y, Z). check_twopair(_, Hand) :- member([X, A], Hand), member([X, B], Hand), member([Y, C], Hand), member([Y, D], Hand), not(A = B), not(C = D), not(X = Y), print_twopair(X, Y). three_pairs(X, Y, Z) :- X = 'A', write('Two Pair -- As and '), next_bestpair(Y, Z). three_pairs(X, Y, Z) :- Y = 'A', write('Two Pair -- As and '), next_bestpair(X, Z). three_pairs(X, Y, Z) :- Z = 'A', write('Two Pair -- As and '), next_bestpair(X, Y). three_pairs(X, Y, Z) :- X = 'K', write('Two Pair -- Ks and '), next_bestpair(Y, Z). three_pairs(X, Y, Z) :- Y = 'K', write('Two Pair -- Ks and '), next_bestpair(X, Z). three_pairs(X, Y, Z) :- Z = 'K', write('Two Pair -- Ks and '), next_bestpair(X, Y). three_pairs(X, Y, Z) :- X = 'Q', write('Two Pair -- Qs and '), next_bestpair(Y, Z). three_pairs(X, Y, Z) :- Y = 'Q', write('Two Pair -- Qs and '), next_bestpair(X, Z). three_pairs(X, Y, Z) :- Z = 'Q', write('Two Pair -- Qs and '), next_bestpair(X, Y). three_pairs(X, Y, Z) :- X = 'J', write('Two Pair -- Js and '), next_bestpair(Y, Z). three_pairs(X, Y, Z) :- Y = 'J', write('Two Pair -- Js and '), next_bestpair(X, Z). three_pairs(X, Y, Z) :- Z = 'J', write('Two Pair -- Js and '), next_bestpair(X, Y). /* If there were another pair of aces, it would be 4 of a kind! */ next_bestpair(X, Y) :- member('K', [X,Y]), write('Ks'), nl. next_bestpair(X, Y) :- member('Q', [X,Y]), write('Qs'), nl. next_bestpair(X, Y) :- member('J', [X,Y]), write('Js'), nl. next_bestpair(X, Y) :- X > Y, write(X), write('s'), nl. next_bestpair(X, Y) :- Y > X, write(Y), write('s'), nl. print_twopair(X, Y) :- write('Two Pair -- '), write(X), write('s and '), write(Y), write('s'), nl. check_pair(Hand) :- member([X, A], Hand), member([X, B], Hand), not(A = B), write('Pair of '), write(X), write('s'), nl. check_highcard(_, Hand) :- member(['A', Suit], Hand), print_highcard('A', Suit). check_highcard(_, Hand) :- member(['K', Suit], Hand), print_highcard('K', Suit). check_highcard(_, Hand) :- member(['Q', Suit], Hand), print_highcard('Q', Suit). check_highcard(_, Hand) :- member(['J', Suit], Hand), print_highcard('J', Suit). check_highcard(Cards, Hand) :- nth1(7, Cards, Card), member([Card, Suit], Hand), print_highcard(Card, Suit). print_highcard(Card, Suit) :- write('High card is a '), write(Card), write(' of '), write(Suit), nl. check_hands(_, _, Hand) :- check_royalflush(Hand). check_hands(_, _, Hand) :- check_straightflush(Hand). check_hands(Cards, _, _) :- check_four(Cards). check_hands(Cards, _, Hand) :- check_fullhouse(Cards, Hand). check_hands(_, Suits, _) :- check_flush(Suits). check_hands(_, _, Hand) :- check_straight(Hand). check_hands(_, _, Hand) :- check_three(Hand). check_hands(Cards, _, Hand) :- check_twopair(Cards, Hand). check_hands(_, _, Hand) :- check_pair(Hand). check_hands(Cards, _, Hand) :- check_highcard(Cards, Hand). play :- nl, write(' *** Texas Hold em Poker Simulation - Prolog style *** '), nl, nl, deck(Deck), deal(Deck, Hand, []), %Hand = [[10,spades],[10,diamonds],[8,clubs],[8,diamonds],['A',spades],[9,clubs],['A',clubs]], print_hand(Hand), nl, split_hand(Hand, Cardsx, Suitsx), msort(Cardsx, Cards), msort(Suitsx, Suits), check_hands(Cards, Suits, Hand), nl.