Difference between revisions of "Hearts Card Game Assignment"
(16 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
=Code To Implement= | =Code To Implement= | ||
+ | {{SMLToImplement|hearts|is_card_valid<br/>are_all_cards_valid<br/>card_score<br/>total_score_of_card_list<br/>total_card_count_for_all_players<br/>is_correct_total_of_cards<br/>is_shenanigans_detected|hearts}} | ||
+ | |||
Given these type definitions: | Given these type definitions: | ||
− | + | <syntaxhighlight lang="sml"> | |
+ | datatype suit = Clubs | Diamonds | Hearts | Spades | ||
datatype rank = Jack | Queen | King | Ace | Num of int | datatype rank = Jack | Queen | King | Ace | Num of int | ||
type card = suit * rank | type card = suit * rank | ||
− | type player = card list</ | + | type player = card list |
− | + | </syntaxhighlight> | |
==cards== | ==cards== | ||
===is_card_valid=== | ===is_card_valid=== | ||
− | Define a function is_card_valid which accepts a card parameter. | + | Define a function <code>is_card_valid</code> which accepts a <code>card</code> parameter. |
− | is_card_valid should evaluate to false if the int value of the Num constructor is | + | |
+ | <code>is_card_valid</code> should evaluate to false if the int value of the <code>Num</code> constructor is | ||
less than 2 or greater than 10. Otherwise, it should evaluate to true | less than 2 or greater than 10. Otherwise, it should evaluate to true | ||
===are_all_cards_valid=== | ===are_all_cards_valid=== | ||
− | Define a function are_all_cards_valid which accepts a card list parameter. | + | Define a function <code>are_all_cards_valid</code> which accepts a <code>card list</code> parameter. |
− | are_all_cards_valid should evaluate to false if any of the cards in the list are | + | |
+ | <code>are_all_cards_valid</code> should evaluate to false if any of the cards in the list are | ||
invalid, and true otherwise. Note: the empty list is valid. | invalid, and true otherwise. Note: the empty list is valid. | ||
− | |||
− | |||
==hearts== | ==hearts== | ||
− | From here on you will no longer need to concern yourself with invalid cards. | + | '''NOTE: From here on you will no longer need to concern yourself with invalid cards. We will not test your functions from here on with invalid cards.''' |
− | Hearts is an trick-taking card game. Further, Hearts is an "evasion-type" card game | + | Hearts is an trick-taking card game. Further, [https://en.wikipedia.org/wiki/Hearts_(card_game) Hearts is an "evasion-type" card game] |
where the objective is to avoid taking positive penalty point cards. The Queen of | where the objective is to avoid taking positive penalty point cards. The Queen of | ||
Spades as well as each and every Heart are positive penalty point cards. Therefore, | Spades as well as each and every Heart are positive penalty point cards. Therefore, | ||
Line 34: | Line 37: | ||
turning in all of their penalty point cards. | turning in all of their penalty point cards. | ||
− | Note: "shenanigans" are devious tricks used especially for an underhand purpose. | + | Note: "[https://www.merriam-webster.com/dictionary/shenanigan shenanigans]" are devious tricks used especially for an underhand purpose. |
===card_score=== | ===card_score=== | ||
− | Define a function card_score which accepts a card parameter. | + | Define a function <code>card_score</code> which accepts a <code>card</code> parameter. |
− | card_score should evaluate to the | + | |
+ | <code>card_score</code> should evaluate to the integer point value of the card as specified below: | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 54: | Line 58: | ||
|} | |} | ||
− | + | Recall: ~ is the unary minus operator in SML. | |
− | + | ||
− | + | ===total_score_of_card_list=== | |
− | + | Define a function <code>total_score_of_card_list</code> which accepts a <code>card list</code> parameter. | |
+ | |||
+ | <code>total_score_of_card_list</code> should evaluate to the sum of the scores of the cards in | ||
+ | the list. | ||
+ | |||
+ | Note: the empty list should evaluate to 0. | ||
+ | |||
+ | ===total_score_of_player_list=== | ||
+ | Define a function <code>total_score_of_player_list</code> which accepts a <code>player list</code> parameter. | ||
+ | |||
+ | <code>total_score_of_player_list</code> should evaluate to the sum of the scores of the players | ||
+ | in the list. | ||
+ | |||
+ | Note: the empty list should evaluate to 0. | ||
+ | |||
+ | Recall: <code>type player = card list</code> | ||
+ | |||
+ | ===total_card_count_for_all_players=== | ||
+ | Define a function <code>total_card_count_for_all_players</code> which accepts a <code>player | ||
+ | list</code> parameter. | ||
− | Recall: | + | <code>total_card_count_for_all_players</code> should evaluate to the total number of cards |
+ | of all the players in the list. | ||
+ | |||
+ | Note: the empty list should evaluate to 0. | ||
+ | |||
+ | This function may use the [https://smlfamily.github.io/Basis/list.html#SIG:LIST.length:VAL length] function in the [https://smlfamily.github.io/Basis/list.html List] structure. | ||
+ | |||
+ | <!-- | ||
+ | Recall: many of the higher ordered functions in List are curried. | ||
+ | |||
+ | This function must appropriately use a higher order function from the [https://smlfamily.github.io/Basis/list.html List] structure | ||
+ | |||
+ | Tip: if you are struggling with type checking errors resulting from curried function calls, try wrapping the arguments in parentheses. | ||
+ | --> | ||
+ | |||
+ | ===is_correct_total_of_cards=== | ||
+ | Perhaps a player neglected to turn in all of his or her cards. | ||
+ | |||
+ | Define a function <code>is_correct_total_of_cards</code> which accepts a <code>player list</code> parameter. <code>is_correct_total_of_cards</code> should return true if the total number of | ||
+ | cards of all the players in the list is 52. Otherwise, it should evaluate to false. | ||
+ | |||
+ | Recall the equality operator in SML is a single =. | ||
+ | |||
+ | ===is_shenanigans_detected=== | ||
+ | Not turning in all of one’s cards could be an honest mistake. Neglecting to turn in point cards, however??? We will declare that "shenanigans!" | ||
+ | |||
+ | Define a function <code>is_shenanigans_detected</code> which accepts a <code>player list</code> parameter. | ||
+ | |||
+ | <code>is_shenanigans_detected</code> should evaluate to true if the total points of all the | ||
+ | players in the list is not 16. Otherwise, it should evaluate to false. | ||
+ | |||
+ | Recall the not equality operator in SML is <>. | ||
+ | |||
+ | Note: there are far more sophisticated checks we could do. We will simply check for not 16. | ||
+ | |||
+ | =Type Summary= | ||
+ | <syntaxhighlight lang="sml"> | ||
+ | val is_card_valid = fn : card -> bool | ||
+ | val are_all_cards_valid = fn : card list -> bool | ||
+ | val card_score = fn : card -> int | ||
+ | val total_score_of_card_list = fn : card list -> int | ||
+ | val total_score_of_player_list = fn : player list -> int | ||
+ | val total_card_count_for_all_players = fn : player list -> int | ||
+ | val is_correct_total_of_cards = fn : player list -> bool | ||
+ | val is_shenanigans_detected = fn : player list -> bool | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | =Test= | ||
+ | {{SMLUnitTesting|run_hearts_testing|hearts}} |
Latest revision as of 18:52, 10 July 2023
Contents
Code To Implement
file: | src/main/sml/hearts/hearts.sml | |
functions: | is_card_valid are_all_cards_valid card_score total_score_of_card_list total_card_count_for_all_players is_correct_total_of_cards is_shenanigans_detected |
Given these type definitions:
datatype suit = Clubs | Diamonds | Hearts | Spades
datatype rank = Jack | Queen | King | Ace | Num of int
type card = suit * rank
type player = card list
cards
is_card_valid
Define a function is_card_valid
which accepts a card
parameter.
is_card_valid
should evaluate to false if the int value of the Num
constructor is
less than 2 or greater than 10. Otherwise, it should evaluate to true
are_all_cards_valid
Define a function are_all_cards_valid
which accepts a card list
parameter.
are_all_cards_valid
should evaluate to false if any of the cards in the list are
invalid, and true otherwise. Note: the empty list is valid.
hearts
NOTE: From here on you will no longer need to concern yourself with invalid cards. We will not test your functions from here on with invalid cards.
Hearts is an trick-taking card game. Further, Hearts is an "evasion-type" card game where the objective is to avoid taking positive penalty point cards. The Queen of Spades as well as each and every Heart are positive penalty point cards. Therefore, players attempt to avoid taking those cards. The Jack of Diamonds is the one favorable card players strive to take (it is worth negative penalty points). For simplicity, we will ignore a common variation which involves a player "shooting the moon" by taking all of the positive penalty point cards.
For the remainder of this assignment you will write code to calculate scores, count the number of cards, as well as detect possible shenanigans of a player/players not turning in all of their penalty point cards.
Note: "shenanigans" are devious tricks used especially for an underhand purpose.
card_score
Define a function card_score
which accepts a card
parameter.
card_score
should evaluate to the integer point value of the card as specified below:
The Queen of Spades | 13 points |
Each Heart | 1 point |
The Jack of Diamonds | minus 10 points |
All other cards | 0 points |
Recall: ~ is the unary minus operator in SML.
total_score_of_card_list
Define a function total_score_of_card_list
which accepts a card list
parameter.
total_score_of_card_list
should evaluate to the sum of the scores of the cards in
the list.
Note: the empty list should evaluate to 0.
total_score_of_player_list
Define a function total_score_of_player_list
which accepts a player list
parameter.
total_score_of_player_list
should evaluate to the sum of the scores of the players
in the list.
Note: the empty list should evaluate to 0.
Recall: type player = card list
total_card_count_for_all_players
Define a function total_card_count_for_all_players
which accepts a player
list
parameter.
total_card_count_for_all_players
should evaluate to the total number of cards
of all the players in the list.
Note: the empty list should evaluate to 0.
This function may use the length function in the List structure.
is_correct_total_of_cards
Perhaps a player neglected to turn in all of his or her cards.
Define a function is_correct_total_of_cards
which accepts a player list
parameter. is_correct_total_of_cards
should return true if the total number of
cards of all the players in the list is 52. Otherwise, it should evaluate to false.
Recall the equality operator in SML is a single =.
is_shenanigans_detected
Not turning in all of one’s cards could be an honest mistake. Neglecting to turn in point cards, however??? We will declare that "shenanigans!"
Define a function is_shenanigans_detected
which accepts a player list
parameter.
is_shenanigans_detected
should evaluate to true if the total points of all the
players in the list is not 16. Otherwise, it should evaluate to false.
Recall the not equality operator in SML is <>.
Note: there are far more sophisticated checks we could do. We will simply check for not 16.
Type Summary
val is_card_valid = fn : card -> bool
val are_all_cards_valid = fn : card list -> bool
val card_score = fn : card -> int
val total_score_of_card_list = fn : card list -> int
val total_score_of_player_list = fn : player list -> int
val total_card_count_for_all_players = fn : player list -> int
val is_correct_total_of_cards = fn : player list -> bool
val is_shenanigans_detected = fn : player list -> bool
Test
source folder: | src/test/sml/hearts |
how to run with CM.make verbosity off: | sml -Ccm.verbose=false run_hearts_testing.sml |
how to run with CM.make verbosity on: | sml run_hearts_testing.sml |
note: ensure that you have removed all printing to receive credit for any assignment.