% FILE: rummy.pl % LINE: Defines all rules related to Rummy gameplay % DATE: February 20, 2021 % write a game where only runs are found % write a game where one player looks for only sets and one looks for only runs % use these to test the performance of each player % write some kind of method where you can pass in the heuristic as an argument % loading prolog files :- consult("melds.pl"). :- consult("demos.pl"). :- consult("human_readable.pl"). :- consult("game_types.pl"). :- consult("test_games.pl"). % name, hand, melds, score player((player1, [], [], 0)). player((player2, [], [], 0)). sets([]). runs([]). % human player for later on human_player(name, [], [], 0). % Deck representation deck([card(ace, hearts, 1),card(two, hearts, 2),card(three, hearts, 3),card(four, hearts, 4),card(five, hearts, 5),card(six, hearts, 6), card(seven, hearts, 7),card(eight, hearts, 8),card(nine, hearts, 9),card(ten, hearts, 10),card(jack, hearts, 11),card(queen, hearts, 12), card(king, hearts, 13),card(ace, clubs, 1),card(two, clubs, 2),card(three, clubs, 3),card(four, clubs, 4),card(five, clubs, 5), card(six, clubs, 6),card(seven, clubs, 7),card(eight, clubs, 8),card(nine, clubs, 9),card(ten, clubs, 10),card(jack, clubs, 11), card(queen, clubs, 12),card(king, clubs, 13),card(ace, diamonds, 1),card(two, diamonds, 2),card(three, diamonds, 3),card(four, diamonds, 4), card(five, diamonds, 5),card(six, diamonds, 6),card(seven, diamonds, 7),card(eight, diamonds, 8),card(nine, diamonds, 9),card(ten, diamonds, 10), card(jack, diamonds, 11),card(queen, diamonds, 12),card(king, diamonds, 13),card(ace, spades, 1),card(two, spades, 2),card(three, spades, 3), card(four, spades, 4),card(five, spades, 5),card(six, spades, 6),card(seven, spades, 7),card(eight, spades, 8),card(nine, spades, 9),card(ten, spades, 10), card(jack, spades, 11),card(queen, spades, 12),card(king, spades, 13)]). % shuffles deck, deal cards to players, deals one card to discard pile init_rummy(Deck, (_, Hand1, _, _), (_, Hand2, _, _), DiscardPile, NDeck, (_, NewHand1, _, _), (_, NewHand2, _, _)) :- shuffle(Deck, NewDeck), deal_out(NewDeck, NewerDeck, Hand1, NewHand1, Hand2, NewHand2, 13), deal_discard(NewerDeck, NDeck, DiscardPile). % Shuffles cards shuffle(Deck, NewDeck) :- random_permutation(Deck, NewDeck). % Deals cards into the player's hands % Deck, NewDeck, Hand1, NewHand1, Hand2 NewHand2, Terminate deal_out([_|Rest], Rest, Hand1, Hand1, Hand2, Hand2, 0). deal_out([First, Second|Rest], NewDeck, Hand1, NewHand1, Hand2, NewHand2, Terminate) :- NewTerm is Terminate - 1, deal_out(Rest, NewDeck, [First|Hand1], NewHand1, [Second|Hand2], NewHand2, NewTerm). % initializes the discard pile by dealing one card into it deal_discard([First|Rest], Rest, [First]). % takes one card from a player's hand and puts it in the discard pile discard([FirstCard|RestHand], DiscardPile, RestHand,[FirstCard|DiscardPile]). % Randomly discards a card from the player's hand random_discard([], _, [], _). random_discard(Hand, DiscardPile, RestHand, [Card|DiscardPile]) :- pick(Hand, Card), human_readable([Card], HRCard), write("DISCARDING: "), write(HRCard), nl, remove(Card, Hand, RestHand). % picks an item at random out of a List (Credit: Prof. Craig Graci) pick(L, Item):- length(L, Length), random(0, Length, RN), nth0(RN, L, Item). % removes and item from a list (Credit: Prof. Craig Graci) remove(_, [], []). remove(First, [First|Rest], Rest). remove(Element, [First|Rest], [First|RestLessElement]) :- remove(Element, Rest, RestLessElement). % takes one card off the top of the deck draw_from_deck([Card|RestDeck], RestDeck, Hand, [Card|Hand]) :- human_readable([Card], HRCard), write("DRAWING FROM DECK: "), write(HRCard), nl. % binds the card on top of the deck to a variable draw([First|_], First). % calculates the total score of each player calculate_score((_, Hand1, Melds1, Score1), (_, Hand2, Melds2, Score2), UpdateScore1, UpdateScore2) :- get_score_from_melds(Melds1, Score1, NewScore1), get_score_from_melds(Melds2, Score2, NewScore2), subtract_out_hand(Hand1, NewScore1, UpdateScore1), subtract_out_hand(Hand2, NewScore2, UpdateScore2). % Calculates the score of every meld a player has. get_score_from_melds([], Score, Score). get_score_from_melds([FirstMeld|RestMelds], OldScore, NewScore) :- get_score_from_meld(FirstMeld, OldScore, UpdateScore), get_score_from_melds(RestMelds, UpdateScore, NewScore). % Calculates the point values contained in each meld get_score_from_meld([], Score, Score). get_score_from_meld([card(_, _, 1)|RestCards], OldScore, NewScore) :- UpdateScore is OldScore + 5, get_score_from_meld(RestCards, UpdateScore, NewScore). get_score_from_meld([card(_, _, 2)|RestCards], OldScore, NewScore) :- UpdateScore is OldScore + 5, get_score_from_meld(RestCards, UpdateScore, NewScore). get_score_from_meld([card(_, _, 3)|RestCards], OldScore, NewScore) :- UpdateScore is OldScore + 5, get_score_from_meld(RestCards, UpdateScore, NewScore). get_score_from_meld([card(_, _, 4)|RestCards], OldScore, NewScore) :- UpdateScore is OldScore + 5, get_score_from_meld(RestCards, UpdateScore, NewScore). get_score_from_meld([card(_, _, 5)|RestCards], OldScore, NewScore) :- UpdateScore is OldScore + 5, get_score_from_meld(RestCards, UpdateScore, NewScore). get_score_from_meld([card(_, _, 6)|RestCards], OldScore, NewScore) :- UpdateScore is OldScore + 5, get_score_from_meld(RestCards, UpdateScore, NewScore). get_score_from_meld([card(_, _, 7)|RestCards], OldScore, NewScore) :- UpdateScore is OldScore + 5, get_score_from_meld(RestCards, UpdateScore, NewScore). get_score_from_meld([card(_, _, 8)|RestCards], OldScore, NewScore) :- UpdateScore is OldScore + 5, get_score_from_meld(RestCards, UpdateScore, NewScore). get_score_from_meld([card(_, _, 9)|RestCards], OldScore, NewScore) :- UpdateScore is OldScore + 5, get_score_from_meld(RestCards, UpdateScore, NewScore). get_score_from_meld([card(_, _, 10)|RestCards], OldScore, NewScore) :- UpdateScore is OldScore + 10, get_score_from_meld(RestCards, UpdateScore, NewScore). get_score_from_meld([card(_, _, 11)|RestCards], OldScore, NewScore) :- UpdateScore is OldScore + 10, get_score_from_meld(RestCards, UpdateScore, NewScore). get_score_from_meld([card(_, _, 12)|RestCards], OldScore, NewScore) :- UpdateScore is OldScore + 10, get_score_from_meld(RestCards, UpdateScore, NewScore). get_score_from_meld([card(_, _, 13)|RestCards], OldScore, NewScore) :- UpdateScore is OldScore + 10, get_score_from_meld(RestCards, UpdateScore, NewScore). % Subtracts the point values contained in a player's hand from the score provided. subtract_out_hand([], Score, Score). subtract_out_hand([card(_, _, 1)|RestCards], Score, NewScore) :- UpdateScore is Score - 5, subtract_out_hand(RestCards, UpdateScore, NewScore). subtract_out_hand([card(_, _, 2)|RestCards], Score, NewScore) :- UpdateScore is Score - 5, subtract_out_hand(RestCards, UpdateScore, NewScore). subtract_out_hand([card(_, _, 3)|RestCards], Score, NewScore) :- UpdateScore is Score - 5, subtract_out_hand(RestCards, UpdateScore, NewScore). subtract_out_hand([card(_, _, 4)|RestCards], Score, NewScore) :- UpdateScore is Score - 5, subtract_out_hand(RestCards, UpdateScore, NewScore). subtract_out_hand([card(_, _, 5)|RestCards], Score, NewScore) :- UpdateScore is Score - 5, subtract_out_hand(RestCards, UpdateScore, NewScore). subtract_out_hand([card(_, _, 6)|RestCards], Score, NewScore) :- UpdateScore is Score - 5, subtract_out_hand(RestCards, UpdateScore, NewScore). subtract_out_hand([card(_, _, 7)|RestCards], Score, NewScore) :- UpdateScore is Score - 5, subtract_out_hand(RestCards, UpdateScore, NewScore). subtract_out_hand([card(_, _, 8)|RestCards], Score, NewScore) :- UpdateScore is Score - 5, subtract_out_hand(RestCards, UpdateScore, NewScore). subtract_out_hand([card(_, _, 9)|RestCards], Score, NewScore) :- UpdateScore is Score - 5, subtract_out_hand(RestCards, UpdateScore, NewScore). subtract_out_hand([card(_, _, 10)|RestCards], Score, NewScore) :- UpdateScore is Score - 10, subtract_out_hand(RestCards, UpdateScore, NewScore). subtract_out_hand([card(_, _, 11)|RestCards], Score, NewScore) :- UpdateScore is Score - 10, subtract_out_hand(RestCards, UpdateScore, NewScore). subtract_out_hand([card(_, _, 12)|RestCards], Score, NewScore) :- UpdateScore is Score - 10, subtract_out_hand(RestCards, UpdateScore, NewScore). subtract_out_hand([card(_, _, 13)|RestCards], Score, NewScore) :- UpdateScore is Score - 10, subtract_out_hand(RestCards, UpdateScore, NewScore).