At the end of each course, you will be working on building a program that estimates the chances of each hand winning in poker in a situation described by an input file. In this portion of the project, you are going write some functions that work with cards (specifically, a struct that represents a card): printing them in human-readable format, converting the pair of letters that describe a card back into a struct (which gets used to read the input from a file), etc. There is a lot that will be required to complete the project that you will learn in the later courses (e.g., arrays, strings, dynamic memory allocation, file IO). To make it so you can still run the poker simulation when you complete this project, we have provided object files (.o) for the later parts. The included Makefile will build your cards.c with our .o files if you do: make poker You'll write all these parts later on, when you finish Courses 3 and 4 and have learned the corresponding concepts. In the meantime, you can test your functions for this assignment by writing any code you want in my-test-main.c. If you do "make" (or "make test") then the included Makefile will build this and link it with your cards.o (compiling that if needed). To get started, take a look at cards.h. You will see that it starts by defining an enum suits (SPADES, HEARTS, DIAMONDS, and CLUBS). This enum also has NUM_SUITS, which will have a numeric value of 4 (indicating how many suits there are), and can also be used to indicate an invalid suit. Next, you will see a struct for a card. This struct has two parts, a value (2,3,4,5,6,7,8,9,10,J,Q,K,A) and a suit (s,h,d,c). Following the struct declaration, there are some #defines for constants for the values of Ace, King, Queen, and Jack. Accordingly, a card's value should be between 2 and 14 (inclusive). There is also an enum for the hand ranking (what kind of poker hand you get). We won't be doing anything with these at this point, except for writing a function to convert from the enumerated values to a string. Last are some function prototypes. You will write each of these in cards.c. Now go into cards.c, and write each of these functions. Here are the specifics: - void assert_card_valid(card_t c); This function should use assert() to check that the card passed in has valid values. In particular, its value should be between 2 and VALUE_ACE (inclusive of both), and its suit should be between SPADES and CLUBS (inclusive of both). - const char * ranking_to_string(hand_ranking_t r); This function should convert the hand_ranking_t enumerated value passed in to a string that describes it. Remember that Drew showed you a nice way to do this with emacs keyboard macros! - char value_letter(card_t c); This function should return the character that textually represents the value of the passed-in card. For values 2-9, this should be that digit. For 10, it should be '0', and for Jack, Queen, King, and Ace, it should be 'J', 'Q', 'K', and 'A' respectively. Hint: remember everything is a number. For example, the character '0' has the decimal value 48, and the character '5' has the decimal value 53, so you could represent '5' as '0' + 5. - char suit_letter(card_t c); This function should return the letter that textually represents the suit of the card passed in ('s', 'h', 'd', or 'c' for SPADES, HEARTS, DIAMONDS, or CLUBS). - void print_card(card_t c); This function should print out the textual representation of the card (hint: use the functions you previously wrote). It should print the value first, then the suit. For example, As (for Ace of spades) 0d (for 10 of diamonds) Kc (for King of clubs) etc. This function should not print any additional spaces or newlines after the card's text. - card_t card_from_letters(char value_let, char suit_let); This function should make and return a card_t whose value and suit correspond to the letters passed in. If the values passed in are invalid, you should use assert() or print an error message and exit(EXIT_FAILURE). - card_t card_from_num(unsigned c); This function should take a number from 0 (inclusive) to 52 (exclusive) and map it uniquely to a card value/suit combination. Exactly how you map the numbers to values/suits is up to you, but you must guarantee that each valid value/suit combination corresponds to exactly one input value in the range [0,52). Hint: you may want to use the mod operator % to find the remainder of a number divided by 13. (In Course 3, this function will be used to make a deck of cards by iterating over that range and calling it once for each value--you just need to learn about arrays first so you have a place to put all those cards.) ---------------------------------------------------- Once you have done all of these (and tested them to your satisfaction with my-test-main.c), you can make poker and try out the poker odds computation. It requires one command line argument--the input file to read. In the input file, each line corresponds to one hand and lists the cards (with textual representation you were working with above). It also has placeholders for future cards, which are a ? followed by a number. For example, this input: As Ah Kc Qd 6c ?0 ?1 2c 3d Kc Qd 6c ?0 ?1 Ks Qs Kc Qd 6c ?0 ?1 describes 3 hands (as might occur in a game of Texas Hold'em). All three hands share the King of clubs, the Queen of diamonds, and the 6 of clubs (called the "flop" in Texas Hold'em--these are the 3rd, 4th, and 5th cards). Each hand has its own private cards to start (the first has the Ace of Spades and the Ace of Hearts, for example). The remainder of the hand will be played by dealing two more cards (?0 and ?1), which will be shared by the three hands. You could also craft an input where each player's cards are private (no cards shared), such as this: As Kh ?0 ?1 ?2 Ac Kc ?3 ?4 ?5 Ad Ah ?6 ?7 ?8 9 cards remain in the future (?0 through ?8), each appearing exactly once in one hand.