summaryrefslogtreecommitdiff
path: root/c3prj1_deck
diff options
context:
space:
mode:
authorHaidong Ji2022-04-15 15:51:30 -0500
committerHaidong Ji2022-04-15 15:51:30 -0500
commit442a49ad5a48d417345959b903ae6a6d32d55759 (patch)
treec7127bb497e5e439018b1915e0136eec2c9cb124 /c3prj1_deck
Great C programming funHEADmaster
Excellent fundamentals and displine training, many tools and techniques exercises: gdb, emacs, valgrind, git
Diffstat (limited to 'c3prj1_deck')
-rw-r--r--c3prj1_deck/.gitignore3
-rw-r--r--c3prj1_deck/Makefile8
-rw-r--r--c3prj1_deck/README176
l---------c3prj1_deck/cards.c1
l---------c3prj1_deck/cards.h1
-rw-r--r--c3prj1_deck/deck-c4.obin0 -> 4752 bytes
-rw-r--r--c3prj1_deck/deck.c75
-rw-r--r--c3prj1_deck/deck.h22
-rw-r--r--c3prj1_deck/grade.txt14
-rw-r--r--c3prj1_deck/test-deck.obin0 -> 11872 bytes
10 files changed, 300 insertions, 0 deletions
diff --git a/c3prj1_deck/.gitignore b/c3prj1_deck/.gitignore
new file mode 100644
index 0000000..d7502ed
--- /dev/null
+++ b/c3prj1_deck/.gitignore
@@ -0,0 +1,3 @@
+deck.o
+cards.o
+test-deck
diff --git a/c3prj1_deck/Makefile b/c3prj1_deck/Makefile
new file mode 100644
index 0000000..28b3c52
--- /dev/null
+++ b/c3prj1_deck/Makefile
@@ -0,0 +1,8 @@
+CFLAGS=-ggdb3 -Wall -Werror -pedantic -std=gnu99
+GIVEN_OBJS=deck-c4.o eval-c4.o future.o input.o main.o
+MY_OBJS=cards.o deck.o eval.o
+
+test-deck: deck.o test-deck.o deck-c4.o cards.o
+ gcc -o test-deck -ggdb3 deck.o test-deck.o deck-c4.o cards.o
+clean:
+ rm test poker cards.o my-test-main.o *~
diff --git a/c3prj1_deck/README b/c3prj1_deck/README
new file mode 100644
index 0000000..1697fc6
--- /dev/null
+++ b/c3prj1_deck/README
@@ -0,0 +1,176 @@
+Decks (sets of cards)
+---------------------
+
+Note: if you have not completed the course 2 poker projects,
+please use the fast-forward command to complete them first!
+
+Now that you have learned about arrays, you are ready
+to start working with decks and hands of cards (represented
+as arrays of cards). You will be using the card.c
+file from your Course 2 project, as this project builds
+on the same card_t type. If you look in deck.h,
+you will find the type declaration for a deck of cards:
+
+struct deck_tag {
+ card_t ** cards;
+ size_t n_cards;
+};
+typedef struct deck_tag deck_t;
+
+We'll use the same type for a deck of cards or a hand
+of cards, since both are just a set of cards.
+
+We'll note that we could have chosen to make an array
+of cards (card_t * cards) but instead decided to make
+an array of card pointers (card_t ** cards). You may
+wonder why we selected this design. With this design,
+when you shuffle an array, you will move the pointers
+around, but they will point to card_ts that stay in the
+same place. This means that if you have OTHER pointers
+(as you will have in Course 4 to handle unknown cards),
+they will still point to the right place.
+
+For example, if you have (Ah,Ks,Qc,?0):
+
+ Ah Ks Qc ?0<----to_replace
+ ^ ^ ^ ^
+ | | | |
+ | | | |
+ | | | |
+ +--|--+--|--+--|--+--|--+
+arr->| | | | | | | | |
+ +-----+-----+-----+-----+
+
+and you shuffle the pointers in the array
+(yielding, e.g, Ks, ?0, Ah, Qc) :
+
+ /------\
+ V \
+ Ah Ks | Qc ?0<----to_replace
+ ^ | ^ ^
+ ____/ \ \ /
+ / ___\___\___/
+ / / \ ---
+ +--|--+--|--+--\--+--\--+
+arr->| | | | | | | | |
+ +-----+-----+-----+-----+
+
+the to_replace pointer still points at ?0
+with no other changes. If we had an array
+of cards and shuffled them directly, it would
+be much harder to do the card replacement later.
+
+
+First, you will write four functions in deck.c:
+
+ - void print_hand(deck_t * hand);
+ This should print out the contents of a hand.
+ It should print each card (recall that
+ you wrote print_card in Course 2), and
+ a space after each card. Do not put
+ a newline after the hand, as this
+ function gets called to print a hand
+ in the middle of a line of output.
+
+
+ - int deck_contains(deck_t * d, card_t c);
+ This function should check if a deck
+ contains a particular card or not. If
+ the deck does contain the card, this
+ function should return 1. Otherwise,
+ it should return 0.
+ (You will use this later to
+ build the deck of remaining cards
+ which are not in any player's hand).
+
+ - void shuffle(deck_t * d);
+ This function takes in a deck an shuffles
+ it, randomly permuting the order of the cards.
+ There are MANY valid ways to shuffle a deck
+ of cards---we'll leave the specifics
+ of the algorithm design up to you. However,
+ you will want to use random() to generate
+ pseudo-random numbers. (Pseudo-random
+ numbers are quite sufficient here,
+ since they are not used for security
+ purposes). Note that you should not need to
+ use the 'srand' function.
+
+ We will note that in trying to devise
+ this algorithm, you should not
+ try to shuffle a deck of cards "normally".
+ Instead, you should take a small number
+ of cards, and think about ways
+ to shuffle them that involve using
+ random numbers to swap their order,
+ or pick positions for them, or
+ similar principles.
+
+- void assert_full_deck(deck_t * d);
+ This function should check that
+ the passed in deck contains ever
+ valid card exactly once. If
+ the deck has any problems, this function
+ should fail an assert. This will
+ be used to help you test your deck
+ shuffling: we will shuffle
+ a full deck, then call assert_full_deck,
+ so that you can identfiy problems with
+ the deck. You can print
+ any error messages you want
+ if there is a problem.
+ Hint: you already wrote deck_contains.
+
+------------
+Once you have completed these functions, you should run
+
+make test-deck
+
+This will build the test-deck program which we
+have provided which runs some test cases on your functions.
+There is no one single right output, as you may shuffle
+your deck any way that you want. However, you should
+read through the output and see if things make sense.
+The first deck is built by using your card_from_num
+function (from Course 2) for each value in the
+range [0,52). Then the deck is shuffled
+a couple times, with the results printed.
+We call assert_full_deck on each of these.
+
+Next we make a 5 card hand, and test
+deck_contains on it, shuffle, and repeat
+the process a few times.
+
+The last thing we do is take the 5 card
+hand and shuffle it 50,000,000 (50 Million)
+times, counting how often each hand occurs.
+In an ideal case, each of the 120 possible
+5-card hands would appear equally often (0.833%
+of the time). If your shuffle is close
+to this, then it is good. If it is drastically
+off, that is bad.
+
+Since this can take a while, the test
+program will print a '.' ever 500,000
+shuffles to let you know it isn't stuck.
+
+When it finishes, it will print out the
+frequency (and ordering) of the most and least
+common hands. For my shuffling algorithm,
+these were 0.836496% and 0.829262% respectively,
+which is quite good. If you end up with
+things in the 0.823% (min) to 0.843% (max) range, that's
+great. If its in the 0.818%(min) to 0.848% (max) range,
+that's good enough. If you are outside of that, you
+should try to work on your shuffling algorithm
+to make sure you get good results from your poker
+simulator.
+
+We provide that hands that appear most and least
+often in case it helps you debug.
+
+Once you are satsified with the functionality
+of your code for this part, run grade.
+When you pass, you get the hand evaluation in
+the next part.
+
diff --git a/c3prj1_deck/cards.c b/c3prj1_deck/cards.c
new file mode 120000
index 0000000..1b5fce4
--- /dev/null
+++ b/c3prj1_deck/cards.c
@@ -0,0 +1 @@
+../c2prj1_cards/cards.c \ No newline at end of file
diff --git a/c3prj1_deck/cards.h b/c3prj1_deck/cards.h
new file mode 120000
index 0000000..7a280fd
--- /dev/null
+++ b/c3prj1_deck/cards.h
@@ -0,0 +1 @@
+../c2prj1_cards/cards.h \ No newline at end of file
diff --git a/c3prj1_deck/deck-c4.o b/c3prj1_deck/deck-c4.o
new file mode 100644
index 0000000..5fc5541
--- /dev/null
+++ b/c3prj1_deck/deck-c4.o
Binary files differ
diff --git a/c3prj1_deck/deck.c b/c3prj1_deck/deck.c
new file mode 100644
index 0000000..2757a3c
--- /dev/null
+++ b/c3prj1_deck/deck.c
@@ -0,0 +1,75 @@
+#include "deck.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void print_hand(deck_t *hand) {
+ for (size_t i = 0; i < hand->n_cards; i++) {
+ print_card(*hand->cards[i]);
+ printf(" ");
+ }
+}
+
+int deck_contains(deck_t *d, card_t c) {
+ for (size_t i = 0; i < d->n_cards; i++) {
+ if (d->cards[i]->value == c.value && d->cards[i]->suit == c.suit) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void shuffle(deck_t *d) {
+ card_t c;
+ for (size_t i = d->n_cards; i > 0; i--) {
+ int r = rand() % i;
+ c = *d->cards[i - 1];
+ *d->cards[i - 1] = *d->cards[r];
+ // d[i-1] = d[r];
+ *d->cards[r] = c;
+ }
+}
+
+void assert_full_deck(deck_t *d) {
+ card_t temp;
+ for (int i = 0; i <= 51; i++) {
+ temp = card_from_num(i);
+ assert(deck_contains(d, temp) == 1);
+ }
+}
+
+void add_card_to(deck_t *deck, card_t c) {
+ deck->n_cards++;
+ deck->cards = realloc(deck->cards, deck->n_cards * sizeof(*card_t));
+ deck->cards[deck->n_cards - 1] = &c;
+}
+
+card_t *add_empty_card(deck_t *deck) {
+ card_t *c = malloc(sizeof(card_t));
+ c->value = 0;
+ c->suit = 0;
+ add_card_to(deck, *c);
+ return c;
+}
+
+deck_t *make_deck_exclude(deck_t *excluded_cards) {
+ deck_t *deck = malloc(sizeof(deck_t));
+ deck->n_cards = 0;
+ card_t *c = malloc(sizeof(card_t));
+ for (int i = 0; i < 52; i++) {
+ *c = card_from_num(i);
+ if (deck_contains(excluded_cards, c) == 1) {
+ continue;
+ } else {
+ deck->n_cards++;
+ deck->cards = realloc(deck->cards, deck->n_cards * sizeof(*card_t));
+ deck->cards[deck->n_cards - 1] = c;
+ }
+ }
+ free(c);
+ return deck;
+}
+
+deck_t * build_remaining_deck(deck_t ** hands, size_t n_hands) {
+
+}
diff --git a/c3prj1_deck/deck.h b/c3prj1_deck/deck.h
new file mode 100644
index 0000000..aace099
--- /dev/null
+++ b/c3prj1_deck/deck.h
@@ -0,0 +1,22 @@
+#ifndef DECK_H
+#define DECK_H
+#include "cards.h"
+#include <stdlib.h>
+struct deck_tag {
+ card_t **cards;
+ size_t n_cards;
+};
+typedef struct deck_tag deck_t;
+
+void print_hand(deck_t *hand);
+int deck_contains(deck_t *d, card_t c);
+void shuffle(deck_t *d);
+void assert_full_deck(deck_t *d);
+// The below functions will be done in course 4.
+deck_t *make_deck_exclude(deck_t *excluded_cards);
+void add_card_to(deck_t *deck, card_t c);
+card_t *add_empty_card(deck_t *deck);
+void free_deck(deck_t *deck);
+deck_t *build_remaining_deck(deck_t **hands, size_t n_hands);
+#endif
+//
diff --git a/c3prj1_deck/grade.txt b/c3prj1_deck/grade.txt
new file mode 100644
index 0000000..c5a7eda
--- /dev/null
+++ b/c3prj1_deck/grade.txt
@@ -0,0 +1,14 @@
+Grading at Sat 11 Dec 2021 09:48:04 PM UTC
+Compiling deck.c
+Compiling cards.c
+Linking cards.o deck.o deck-c4.o and the grader's .o file
+Checking the output of all the functions other than shuffle
+Your file matched the expected output
+ - Those functions seem to work!
+Checking your shuffle results with a 6 card hand...
+ Least common hand: 0.131350%
+ Most common hand: 0.147450%
+ Perfectly even is: 0.138888%
+ Excellent!
+
+Overall Grade: A
diff --git a/c3prj1_deck/test-deck.o b/c3prj1_deck/test-deck.o
new file mode 100644
index 0000000..53a80bf
--- /dev/null
+++ b/c3prj1_deck/test-deck.o
Binary files differ