Difference between revisions of "Hearts Card Game Assignment"

From CSE425S Wiki
Jump to navigation Jump to search
 
(6 intermediate revisions by 2 users not shown)
Line 4: Line 4:
 
Given these type definitions:
 
Given these type definitions:
  
<nowiki>datatype suit = Clubs | Diamonds | Hearts | Spades
+
<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</nowiki>
+
type player = card list
 
+
</syntaxhighlight>
 
==cards==
 
==cards==
 
===is_card_valid===
 
===is_card_valid===
Line 21: Line 22:
 
<code>are_all_cards_valid</code> 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.
 
<code>are_all_cards_valid</code> may be tail-recursive or not at your preference.
 
  
 
==hearts==
 
==hearts==
Line 68: Line 67:
  
 
Note: the empty list should evaluate to 0.
 
Note: the empty list should evaluate to 0.
 
<code>total_score_of_card_list</code> may be tail-recursive or not at your preference
 
  
 
===total_score_of_player_list===
 
===total_score_of_player_list===
Line 79: Line 76:
 
Note: the empty list should evaluate to 0.
 
Note: the empty list should evaluate to 0.
  
Recall: type player = card list
+
Recall: <code>type player = card list</code>
  
 
===total_card_count_for_all_players===
 
===total_card_count_for_all_players===
Line 90: Line 87:
 
Note: the empty list should evaluate to 0.
 
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.
 
Recall: many of the higher ordered functions in List are curried.
 
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.
 
  
 
This function must appropriately use a higher order function from the [https://smlfamily.github.io/Basis/list.html List] structure
 
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.
 
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===
 
===is_correct_total_of_cards===
Line 119: Line 118:
  
 
=Type Summary=
 
=Type Summary=
<nowiki>val is_card_valid = fn : card -> bool
+
<syntaxhighlight lang="sml">
 +
val is_card_valid = fn : card -> bool
 
val are_all_cards_valid = fn : card list -> bool
 
val are_all_cards_valid = fn : card list -> bool
 
val card_score = fn : card -> int
 
val card_score = fn : card -> int
Line 126: Line 126:
 
val total_card_count_for_all_players = 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_correct_total_of_cards = fn : player list -> bool
val is_shenanigans_detected = fn : player list -> bool</nowiki>
+
val is_shenanigans_detected = fn : player list -> bool
 +
</syntaxhighlight>
  
 
=Test=
 
=Test=
{{SMLUnitTest|hearts|hearts}}
+
{{SMLUnitTesting|run_hearts_testing|hearts}}

Latest revision as of 18:52, 10 July 2023

Code To Implement

file: src/main/sml/hearts/hearts.sml Smlnj-logo.png
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.

SML Error Messages