summaryrefslogtreecommitdiff
path: root/c2prj1_cards/README
blob: 73848b102eaaf563a1570a6ad755e96acd9bb157 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
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.