Created
October 1, 2010 06:28
-
-
Save pablo-meier/605834 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| %% Top Level | |
| main(Num_Wins) :- | |
| open(hands, read, Fb), | |
| read(Fb, ListOfHands), | |
| play(ListOfHands, Num_Wins). | |
| play([],0). | |
| play([[Hand1,Hand2]|Rst], Num_Wins) :- | |
| winner(Hand1, Hand2, Winner), | |
| (Winner = Hand1, play(Rst,Remaining), Num_Wins is 1 + Remaining ; | |
| play(Rst, Num_Wins)). | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| %% Playing the game. | |
| winner(H1, H2, Winner) :- | |
| sort_hand(H1, Sorted_Hand1), | |
| sort_hand(H2, Sorted_Hand2), | |
| determine_hand(Sorted_Hand1, X1), | |
| determine_hand(Sorted_Hand2, X2), | |
| beats(X1, X2, Verdict), | |
| (Verdict = X1, Winner = H1; | |
| Verdict = X2, Winner = H2; | |
| Verdict = tie, tiebreak(X1, Sorted_Hand1, Sorted_Hand2, SortedWinner), | |
| (SortedWinner = left, Winner = H1 ; | |
| SortedWinner = right, Winner = H2)). | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| %% Tiebreaks | |
| tiebreak(straight_flush, H1, H2, Winner) :- higher_last_card(H1, H2, Winner). | |
| tiebreak(four_of_a_kind, H1, H2, Winner) :- higher_middle_card(H1, H2, Winner). | |
| tiebreak(full_house, H1, H2, Winner) :- higher_middle_card(H1, H2, Winner). | |
| tiebreak(flush, H1, H2, Winner) :- tiebreak(high_card, H1, H2, Winner). | |
| tiebreak(straight, H1, H2, Winner) :- higher_last_card(H1, H2, Winner). | |
| tiebreak(three_of_a_kind, H1, H2, Winner) :- higher_middle_card(H1, H2, Winner). | |
| tiebreak(two_pair, H1, H2, Winner) :- | |
| isolate_pairs(H1, [HighCard1,_], [LowCard1,_], Last1), | |
| isolate_pairs(H2, [HighCard2,_], [LowCard2,_], Last2), | |
| (beats_with_hand(H1, HighCard1, H2, HighCard2, Winner), | |
| Winner \= tie; | |
| beats_with_hand(H1, LowCard1, H2, LowCard2, Winner), | |
| Winner \= tie; | |
| beats_with_hand(H1, Last1, H2, Last2, Winner)). | |
| tiebreak(pair, H1, H2, Winner) :- | |
| isolate_pair(H1, [PairCard1,_], Rst1), | |
| isolate_pair(H2, [PairCard2,_], Rst2), | |
| (beats_with_hand(H1, PairCard1, H2, PairCard2, Winner), Winner \= tie ; | |
| tiebreak(high_card, Rst1, Rst2, Winner)). | |
| tiebreak(high_card, H1, H2, X) :- | |
| reverse(H1, RevH1), | |
| reverse(H2, RevH2), | |
| highest_card_chain(RevH1, RevH2, X). | |
| beats_with_hand(H1, C1, H2, C2, X) :- | |
| beats(C1, C2, C1), X = left ; | |
| beats(C1, C2, C2), X = right ; | |
| X = tie. | |
| % Really ugly. How to better do this? | |
| isolate_pairs(Hand, High_Pair, Low_Pair, Last) :- | |
| [[V1,S1],[V2,S2],[V3,S3],[V4,S4],[V5,S5]] = Hand, | |
| (V5 = V4, High_Pair = [[V4,S4],[V5,S5]], | |
| (V3 = V2, Low_Pair = [[V3,S3],[V2,S2]], Last = [V1,S1] ; | |
| V1 = V2, Low_Pair = [[V1,S1],[V2,S2]], Last = [V3,S3])) ; | |
| (Low_Pair = [[V1,S1],[V2,S2]], | |
| High_Pair = [[V3,S3],[V4,S4]], | |
| Last = [V5,S5]). | |
| isolate_pair(Hand, Pair, Rst) :- | |
| [[V1,S1],[V2,S2],[V3,S3],[V4,S4],[V5,S5]] = Hand, | |
| (V1 = V2, Pair = [[V1,S1],[V2,S2]], Rst = [[V3,S3],[V4,S4],[V5,S5]] ; | |
| V2 = V3, Pair = [[V3,S3],[V2,S2]], Rst = [[V1,S1],[V4,S4],[V5,S5]] ; | |
| V4 = V3, Pair = [[V3,S3],[V4,S4]], Rst = [[V1,S1],[V2,S2],[V5,S5]] ; | |
| V4 = V5, Pair = [[V5,S5],[V4,S4]], Rst = [[V1,S1],[V2,S2],[V3,S3]]). | |
| highest_card_chain([H1|T1], [H2|T2], X) :- | |
| beats(H1,H2,Verdict), | |
| (Verdict = H1, X = left ; | |
| Verdict = H2, X = right ; | |
| Verdict = tie, highest_card_chain(T1,T2,X)). | |
| higher_last_card(H1,H2,Winner) :- | |
| H1 = [_,_,_,_,[V1,_]], | |
| H2 = [_,_,_,_,[V2,_]], | |
| beats(V1,V2,Higher), | |
| (Higher = V1, Winner = left ; | |
| Higher = V2, Winner = right). | |
| higher_middle_card(H1, H2, Winner) :- | |
| H1 = [_,_,[V1,_],_,_], | |
| H2 = [_,_,[V2,_],_,_], | |
| beats(V1,V2,Higher), | |
| (Higher = V1, Winner = left; | |
| Higher = V2, Winner = right). | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| %% Hand determination | |
| determine_hand([[10,X],[jack,X],[queen,X],[king,X],[ace,X]], royal_flush). | |
| determine_hand([[A,X],[B,X],[C,X],[D,X],[E,X]], straight_flush) :- | |
| successor(E,D), successor(D,C), successor(C,B), successor(B,A). | |
| determine_hand([[C,_],[A,_],[A,_],[A,_],[B,_]], four_of_a_kind) :- | |
| C = A ; B = A. | |
| determine_hand([[A,_],[B,_],[C,_],[D,_],[E,_]], full_house) :- | |
| A = B, D = E, (C = D ; C = B). | |
| determine_hand([[_,X],[_,X],[_,X],[_,X],[_,X]], flush). | |
| determine_hand([[A,_],[B,_],[C,_],[D,_],[E,_]], straight) :- | |
| successor(E,D), successor(D,C), successor(C,B), successor(B,A). | |
| determine_hand([[A,_],[B,_],[C,_],[D,_],[E,_]], three_of_a_kind) :- | |
| (A = B, B = C); (B = C, C = D); (C = D, D = E). | |
| determine_hand([[A,_],[A,_],[B,_],[B,_],[_,_]], two_pair). | |
| determine_hand([[_,_],[A,_],[A,_],[B,_],[B,_]], two_pair). | |
| determine_hand([[A,_],[A,_],[_,_],[B,_],[B,_]], two_pair). | |
| determine_hand([[A,_],[B,_],[C,_],[D,_],[E,_]], pair) :- | |
| A = B; B = C; C = D; D = E. | |
| determine_hand(_,high_card). | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| %% Hand sorting (for easier pattern matching). | |
| sort_hand([], []). | |
| sort_hand([H|T], Sorted) :- | |
| filter_by_high_card(H,T,Lower,Higher), | |
| sort_hand(Lower,SortedLower), | |
| sort_hand(Higher,SortedHigher), | |
| append(SortedLower, [H|SortedHigher], Sorted). | |
| filter_by_high_card(_, [], [], []). | |
| filter_by_high_card(Pivot, [H|T], [H|Lower], Higher) :- | |
| beats(Pivot,H,Z), | |
| (Z = Pivot ; Z = tie), | |
| filter_by_high_card(Pivot, T, Lower, Higher). | |
| filter_by_high_card(Pivot, [H|T], Lower, [H|Higher]) :- | |
| beats(Pivot,H,H), | |
| filter_by_high_card(Pivot, T, Lower, Higher). | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| %% Card and Hand Precedence | |
| beats([V,_],[V,_],tie). | |
| beats([V1,S],[V2,_],[V1,S]) :- value_greater_than(V1,V2). | |
| beats([V1,_],[V2,S],[V2,S]) :- value_greater_than(V2,V1). | |
| beats(X,X,tie). | |
| beats(X,Y,X) :- value_greater_than(X,Y). | |
| beats(X,Y,Y) :- value_greater_than(Y,X). | |
| successor(royal_flush, straight_flush). successor(straigh_flush, four_of_a_kind). | |
| successor(four_of_a_kind, full_house). successor(full_house, flush). | |
| successor(flush, straight). successor(straight, three_of_a_kind). | |
| successor(three_of_a_kind, two_pair). successor(two_pair, pair). | |
| successor(pair, high_card). | |
| successor(ace,king). successor(king,queen). successor(queen,jack). | |
| successor(jack,10). successor(10,9). successor(9,8). | |
| successor(8,7). successor(7,6). successor(6,5). | |
| successor(5,4). successor(4,3). successor(3,2). | |
| value_greater_than(X,Y) :- | |
| successor(X,P), | |
| (Y = P; | |
| value_greater_than(P,Y)). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Prolog newb here, any tips on how to call/use this?