diff options
author | Haidong Ji | 2022-04-15 15:51:30 -0500 |
---|---|---|
committer | Haidong Ji | 2022-04-15 15:51:30 -0500 |
commit | 442a49ad5a48d417345959b903ae6a6d32d55759 (patch) | |
tree | c7127bb497e5e439018b1915e0136eec2c9cb124 /c3prj1_deck |
Excellent fundamentals and displine training, many tools and techniques
exercises: gdb, emacs, valgrind, git
Diffstat (limited to 'c3prj1_deck')
-rw-r--r-- | c3prj1_deck/.gitignore | 3 | ||||
-rw-r--r-- | c3prj1_deck/Makefile | 8 | ||||
-rw-r--r-- | c3prj1_deck/README | 176 | ||||
l--------- | c3prj1_deck/cards.c | 1 | ||||
l--------- | c3prj1_deck/cards.h | 1 | ||||
-rw-r--r-- | c3prj1_deck/deck-c4.o | bin | 0 -> 4752 bytes | |||
-rw-r--r-- | c3prj1_deck/deck.c | 75 | ||||
-rw-r--r-- | c3prj1_deck/deck.h | 22 | ||||
-rw-r--r-- | c3prj1_deck/grade.txt | 14 | ||||
-rw-r--r-- | c3prj1_deck/test-deck.o | bin | 0 -> 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 Binary files differnew file mode 100644 index 0000000..5fc5541 --- /dev/null +++ b/c3prj1_deck/deck-c4.o 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 Binary files differnew file mode 100644 index 0000000..53a80bf --- /dev/null +++ b/c3prj1_deck/test-deck.o |