% card definitions card(ace, spades). card(king, spades). card(queen, spades). card(jack, spades). card(10, spades). card(9, spades). card(8, spades). card(7, spades). card(6, spades). card(5, spades). card(4, spades). card(3, spades). card(2, spades). card(ace, hearts). card(king, hearts). card(queen, hearts). card(jack, hearts). card(10, hearts). card(9, hearts). card(8, hearts). card(7, hearts). card(6, hearts). card(5, hearts). card(4, hearts). card(3, hearts). card(2, hearts). card(ace, clubs). card(king, clubs). card(queen, clubs). card(jack, clubs). card(10, clubs). card(9, clubs). card(8, clubs). card(7, clubs). card(6, clubs). card(5, clubs). card(4, clubs). card(3, clubs). card(2, clubs). card(ace, diamonds). card(king, diamonds). card(queen, diamonds). card(jack, diamonds). card(10, diamonds). card(9, diamonds). card(8, diamonds). card(7, diamonds). card(6, diamonds). card(5, diamonds). card(4, diamonds). card(3, diamonds). card(2, diamonds). % Points of the cards points(card(king, _), 3). points(card(queen, _), 2). points(card(X, _), 0) :- X\=king, X\=queen. % case when the stack contains all figures all_figures([card(X, _), card(Y, _)]) :- (X==king; X==queen; X==jack), (Y==king; Y==queen; Y==jack). % points value of a stack value([X,Y], S) :- points(X, S1), points(Y, S2), all_figures([X, Y]), S is (5 + S1 + S2), !. value([X,Y], S) :- points(X, S1), points(Y, S2), S is S1 + S2. % the all_figure rules was applied to the new cards. % Insertion of an element at the end of a list insert([], Y, [Y]). insert([X|T], Y, [X |T1]):- insert(T, Y, T1). % Produce the list of all cards compose(L1, L2) :- card(X, Y), not(member(card(X, Y), L1)), insert(L1, card(X, Y), L3), compose(L3, L2), !. compose(L1, L2) :- L2 = L1. % Retract a card from a random position in the list of cards retract_card(List1, Index, List2, Elem) :- nth1(Index, List1, Elem), delete(List1, Elem, List2). % Randomly pick two cards pick_Player(4-2, [C1, C2], [C1, C2], []) :- !. pick_Player(B, L, [C1, C2], L2) :- B \= 2, N1 is random(B), N1 \= 0, retract_card(L, N1, L1, C1), N2 is random(B-1), N2 \= N1, N2 \= 0, retract_card(L1, N2, L2, C2), !. pick_Player(B, L, P , L2) :- pick_Player(B, L, P, L2). % Case when the ace of clubs is received: deduct 6 points ace_of_clubs([card(ace, clubs), _], -6) :- !. ace_of_clubs([_, card(ace, clubs)], -6) :- !. ace_of_clubs([_, _], 0). wins(P1, P2, J1, _) :- P1 > P2, writef('%t wins this round\n', [J1]). wins(P1, P2, _, J2) :- P2 > P1, writef('%t wins this round\n', [J2]). wins(P1, P2, _, _) :- P1 == P2, write('Nobody wins this round'), nl. % Calculates the points of the players for one round round(Player1, Player2, Stack1, Stack2, Points1, Points2) :- value(Stack1, Points1), writef('\nThe stack of %t has %t points\n', [Player1, Points1]), value(Stack2, Points2), writef('The stack of %t has %t points\n', [Player2, Points2]), wins(Points1, Points2, Player1, Player2). % Scores each round of the game player(B, Stack, Player1, Player2, Score1, Score2) :- writef('Describe the stack of %t :', [Player1]), nl, pick_Player(B, Stack, Stack1, StackR1), ace_of_clubs(Stack1, R1), writef('\t\t'), write(Stack1), nl, writef('Describe the stack of %t :', [Player2]), nl, pick_Player(B-2, StackR1, Stack2, StackR2), ace_of_clubs(Stack2, R2), writef('\t\t'), write(Stack2), nl, round(Player1, Player2, Stack1, Stack2, Points1, Points2), NewScore1 is Score1 + Points1 + R1, NewScore2 is Score2 + Points2 + R2, %don't allow the scores to become negative ((NewScore1 =< 0, NS1 is 0); NS1 is NewScore1), ((NewScore2 =< 0, NS2 is 0); NS2 is NewScore2), % if the opponent has zero pints, add 10 points ((NS1 =:= 0, NNS2 is NS2 +10); NNS2 is NS2), ((NS2 =:= 0, NNS1 is NS1 +10); NNS1 is NS1), writef('\n%t has a total of %t points\n', [Player1, NNS1]), writef('%t has a total of %t points\n', [Player2, NNS2]), StackR2 \= [], write('-------------------------------'), nl, write('Do you want to continue [y/n]: '), get(Response), writef('\n-------------------------------'), nl, Response == 121, NewB is B-4, player(NewB, StackR2, Player1, Player2, NNS1, NNS2). player(_, _, Player1, _, Score1, Score2) :- Score1 > Score2, writef('\n%t wins the game. Goodbye!', [Player1]), nl. player(_, _, _, Player2, Score1, Score2) :- Score2 > Score1, writef('\n%t wins the game. Goodbye!', [Player2]), nl. % Start the game with 52 cards game(Player1, Player2) :- compose([], Stack), player(52, Stack, Player1, Player2, 0, 0). % Start the game with the query % game(john, peter). %Note: if you interpreted some rules of the game in a different way (rules 3,4,5), % that's OK too as long as it is a plausible interpretation.