summaryrefslogtreecommitdiff
path: root/c2prj1_cards
diff options
context:
space:
mode:
authorHaidong Ji2022-04-15 15:51:30 -0500
committerHaidong Ji2022-04-15 15:51:30 -0500
commit442a49ad5a48d417345959b903ae6a6d32d55759 (patch)
treec7127bb497e5e439018b1915e0136eec2c9cb124 /c2prj1_cards
Great C programming funHEADmaster
Excellent fundamentals and displine training, many tools and techniques exercises: gdb, emacs, valgrind, git
Diffstat (limited to 'c2prj1_cards')
-rw-r--r--c2prj1_cards/.gitignore1
-rw-r--r--c2prj1_cards/Makefile9
-rw-r--r--c2prj1_cards/README179
-rw-r--r--c2prj1_cards/cards.c131
-rw-r--r--c2prj1_cards/cards.h38
-rwxr-xr-xc2prj1_cards/deck-c4.obin0 -> 4752 bytes
-rw-r--r--c2prj1_cards/deck.obin0 -> 4144 bytes
-rwxr-xr-xc2prj1_cards/eval-c4.obin0 -> 2504 bytes
-rw-r--r--c2prj1_cards/eval.obin0 -> 10480 bytes
-rw-r--r--c2prj1_cards/future.obin0 -> 3216 bytes
-rw-r--r--c2prj1_cards/grade.txt25
-rw-r--r--c2prj1_cards/input.obin0 -> 5504 bytes
-rw-r--r--c2prj1_cards/main.obin0 -> 5264 bytes
-rw-r--r--c2prj1_cards/my-test-main.c5
14 files changed, 388 insertions, 0 deletions
diff --git a/c2prj1_cards/.gitignore b/c2prj1_cards/.gitignore
new file mode 100644
index 0000000..9daeafb
--- /dev/null
+++ b/c2prj1_cards/.gitignore
@@ -0,0 +1 @@
+test
diff --git a/c2prj1_cards/Makefile b/c2prj1_cards/Makefile
new file mode 100644
index 0000000..be1c5b4
--- /dev/null
+++ b/c2prj1_cards/Makefile
@@ -0,0 +1,9 @@
+CFLAGS=-ggdb3 -Wall -Werror -pedantic -std=gnu99
+GIVEN_OBJS=deck.o eval.o future.o input.o main.o eval-c4.o deck-c4.o
+
+test: cards.o my-test-main.o
+ gcc -o test -ggdb3 cards.o my-test-main.o
+poker: $(GIVEN_OBJS) cards.o
+ gcc -o poker -ggdb3 cards.o $(GIVEN_OBJS)
+clean:
+ rm test poker cards.o my-test-main.o *~
diff --git a/c2prj1_cards/README b/c2prj1_cards/README
new file mode 100644
index 0000000..73848b1
--- /dev/null
+++ b/c2prj1_cards/README
@@ -0,0 +1,179 @@
+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.
diff --git a/c2prj1_cards/cards.c b/c2prj1_cards/cards.c
new file mode 100644
index 0000000..c335826
--- /dev/null
+++ b/c2prj1_cards/cards.c
@@ -0,0 +1,131 @@
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include "cards.h"
+
+
+void assert_card_valid(card_t c) {
+ assert(c.value >= 2 && c.value <= VALUE_ACE);
+ assert(c.suit >= SPADES && c.suit <= CLUBS);
+}
+
+const char * ranking_to_string(hand_ranking_t r) {
+ switch (r) {
+ case STRAIGHT_FLUSH:
+ return "STRAIGHT_FLUSH";
+ case FOUR_OF_A_KIND:
+ return "FOUR_OF_A_KIND";
+ case FULL_HOUSE:
+ return "FULL_HOUSE";
+ case FLUSH:
+ return "FLUSH";
+ case STRAIGHT:
+ return "STRAIGHT";
+ case THREE_OF_A_KIND:
+ return "THREE_OF_A_KIND";
+ case TWO_PAIR:
+ return "TWO_PAIR";
+ case PAIR:
+ return "PAIR";
+ default:
+ return "NOTHING";
+ }
+}
+
+char value_letter(card_t c) {
+ switch(c.value) {
+ case VALUE_ACE:
+ return 'A';
+ case VALUE_KING:
+ return 'K';
+ case VALUE_QUEEN:
+ return 'Q';
+ case VALUE_JACK:
+ return 'J';
+ case 10:
+ return '0';
+ default:
+ return '0' + c.value;
+ }
+}
+
+
+char suit_letter(card_t c) {
+ switch(c.suit) {
+ case SPADES:
+ return 's';
+ case HEARTS:
+ return 'h';
+ case DIAMONDS:
+ return 'd';
+ default:
+ return 'c';
+ }
+
+}
+
+void print_card(card_t c) {
+ printf("%c%c", value_letter(c), suit_letter(c));
+}
+
+card_t card_from_letters(char value_let, char suit_let) {
+ card_t temp;
+ switch(value_let) {
+ case 'A':
+ temp.value = VALUE_ACE;
+ break;
+ case 'K':
+ temp.value = VALUE_KING;
+ break;
+ case 'Q':
+ temp.value = VALUE_QUEEN;
+ break;
+ case 'J':
+ temp.value = VALUE_JACK;
+ break;
+ case '0':
+ temp.value = 10;
+ break;
+ default:
+ temp.value = value_let - '0';
+ break;
+ }
+ switch(suit_let) {
+ case 's':
+ temp.suit = SPADES;
+ break;
+ case 'h':
+ temp.suit = HEARTS;
+ break;
+ case 'd':
+ temp.suit = DIAMONDS;
+ break;
+ case 'c':
+ temp.suit = CLUBS;
+ break;
+ }
+ assert_card_valid(temp);
+ return temp;
+}
+
+card_t card_from_num(unsigned c) {
+ card_t temp;
+ if (c <= 12) {
+ temp.value = c + 2;
+ temp.suit = SPADES;
+ }
+ else if (c > 12 && c <= 25) {
+ temp.value = c % 13 + 2;
+ temp.suit = HEARTS;
+ }
+ else if (c > 25 && c <= 38) {
+ temp.value = c % 13 + 2;
+ temp.suit = DIAMONDS;
+ }
+ else {
+ temp.value = c % 13 + 2;
+ temp.suit = CLUBS;
+ }
+ assert_card_valid(temp);
+ return temp;
+}
diff --git a/c2prj1_cards/cards.h b/c2prj1_cards/cards.h
new file mode 100644
index 0000000..fef0529
--- /dev/null
+++ b/c2prj1_cards/cards.h
@@ -0,0 +1,38 @@
+#ifndef CARD_H
+#define CARD_H
+#define VALUE_ACE 14
+#define VALUE_KING 13
+#define VALUE_QUEEN 12
+#define VALUE_JACK 11
+typedef enum {
+ SPADES,
+ HEARTS,
+ DIAMONDS,
+ CLUBS,
+ NUM_SUITS
+} suit_t;
+
+struct card_tag {
+ unsigned value;
+ suit_t suit;
+};
+typedef struct card_tag card_t;
+typedef enum {
+ STRAIGHT_FLUSH,
+ FOUR_OF_A_KIND,
+ FULL_HOUSE,
+ FLUSH,
+ STRAIGHT,
+ THREE_OF_A_KIND,
+ TWO_PAIR,
+ PAIR,
+ NOTHING
+} hand_ranking_t;
+card_t card_from_num(unsigned c);
+void assert_card_valid(card_t c);
+const char * ranking_to_string(hand_ranking_t r) ;
+char value_letter(card_t c);
+char suit_letter(card_t c) ;
+void print_card(card_t c);
+card_t card_from_letters(char value_let, char suit_let);
+#endif
diff --git a/c2prj1_cards/deck-c4.o b/c2prj1_cards/deck-c4.o
new file mode 100755
index 0000000..5fc5541
--- /dev/null
+++ b/c2prj1_cards/deck-c4.o
Binary files differ
diff --git a/c2prj1_cards/deck.o b/c2prj1_cards/deck.o
new file mode 100644
index 0000000..bddad7c
--- /dev/null
+++ b/c2prj1_cards/deck.o
Binary files differ
diff --git a/c2prj1_cards/eval-c4.o b/c2prj1_cards/eval-c4.o
new file mode 100755
index 0000000..8cca00b
--- /dev/null
+++ b/c2prj1_cards/eval-c4.o
Binary files differ
diff --git a/c2prj1_cards/eval.o b/c2prj1_cards/eval.o
new file mode 100644
index 0000000..364ceb4
--- /dev/null
+++ b/c2prj1_cards/eval.o
Binary files differ
diff --git a/c2prj1_cards/future.o b/c2prj1_cards/future.o
new file mode 100644
index 0000000..a770c6a
--- /dev/null
+++ b/c2prj1_cards/future.o
Binary files differ
diff --git a/c2prj1_cards/grade.txt b/c2prj1_cards/grade.txt
new file mode 100644
index 0000000..8a52657
--- /dev/null
+++ b/c2prj1_cards/grade.txt
@@ -0,0 +1,25 @@
+Grading at Mon 29 Nov 2021 02:19:48 AM UTC
+Compiling cards.c
+Testing card_from_letters
+Passed
+Testing value_letter and suit_letter
+Passed
+Testing print_card
+Passed
+Testing card_from_num
+Passed
+Testing ranking_to_string
+ranking_to_string(STRAIGHT_FLUSH) resulted in STRAIGHT_FLUSH (Correct)
+ranking_to_string(FOUR_OF_A_KIND) resulted in FOUR_OF_A_KIND (Correct)
+ranking_to_string(FULL_HOUSE) resulted in FULL_HOUSE (Correct)
+ranking_to_string(FLUSH) resulted in FLUSH (Correct)
+ranking_to_string(STRAIGHT) resulted in STRAIGHT (Correct)
+ranking_to_string(THREE_OF_A_KIND) resulted in THREE_OF_A_KIND (Correct)
+ranking_to_string(TWO_PAIR) resulted in TWO_PAIR (Correct)
+ranking_to_string(PAIR) resulted in PAIR (Correct)
+ranking_to_string(NOTHING) resulted in NOTHING (Correct)
+Passed
+Testing assert_card_valid
+Passed
+
+Overall Grade: PASSED
diff --git a/c2prj1_cards/input.o b/c2prj1_cards/input.o
new file mode 100644
index 0000000..65cc44b
--- /dev/null
+++ b/c2prj1_cards/input.o
Binary files differ
diff --git a/c2prj1_cards/main.o b/c2prj1_cards/main.o
new file mode 100644
index 0000000..0f486ec
--- /dev/null
+++ b/c2prj1_cards/main.o
Binary files differ
diff --git a/c2prj1_cards/my-test-main.c b/c2prj1_cards/my-test-main.c
new file mode 100644
index 0000000..fefe47e
--- /dev/null
+++ b/c2prj1_cards/my-test-main.c
@@ -0,0 +1,5 @@
+#include "cards.h"
+
+int main(void) {
+
+}