Lab 1: Playing Poker
Objectives
After completing this lab, you should:
- be comfortable with the write-compile-test cycle used in this and future labs
- understand the role of .h and .c source files in multi-file C projects
- be able to describe the flow of control in a procedural language program (as opposed to one written in an object oriented language like Java)
- be able to use most of the C language control flow constructs in your own code
- know how to declare and use composite data types (
structs) in C
Overview
As most students coming into this class have little to no experience programming in a procedural language (such as C), this lab is meant as a warm-up exercise to familiarize you with both the language and development environment.
This lab is based on a Project Euler problem. You are to write a program that determines the winner between two given hands of poker. The original writeup does a perfectly good job of describing the problem, so I won't duplicate it here. Read it thoroughly, then come back here to continue!
Besides just figuring out the answer to the problem we've a few additional implementation requirements for you, as we want to ensure that this lab has the desired effect of getting you comfortable with procedural programming in C and general lab procedures. These requirements are described below.
Preliminaries
For this lab you will be working in the labs/1_pokerlab directory of your
repository.
As always, be sure that you've committed all your previous work and pulled the
latest changes from the central repository before starting this lab. git commit
-a and git pull should take care of this.
You should also pull from your repository (in case we left feedback for
you there) -- do this with git pull.
If you are still confused or uncertain at this point about how to use git to
pull, commit, or push lab files, seek help from a TA! The prelimlab
summary may help refresh your memory, too.
Implementation Requirements and Testing Procedures
In the poker.h and poker.c files (found in the lab directory) you will find
declarations and definitions of various structures, datatypes, and functions
that you'll be using and implementing to solve the problem at hand. While you
may certainly add more functions, it is mandatory that you complete the ones we
specify (hopefully, you'll find the suggested breakdown useful).
Unit Testing
The best way to work on your functions is to incrementally test them with the
suite of unit tests provided in the all-tests.c file. To run these tests,
simply issue the command make tests in the lab directory. Initially, you'll
see output like this:
Collecting all unit tests ...
Compiling tests-main.c ...
Running tests ...
..FFFFFFFFFFFFF
There were 13 failures:
1) test_string_to_hand: all-tests.c:90: expected <5C 3D TS AD 2H> but was < C >
2) test_sort_hand: all-tests.c:103: expected <2H 3D 5C TS AD> but was <5C 3D TS AD 2H>
3) test_is_onepair: all-tests.c:115: assert failed
4) test_is_twopairs: all-tests.c:123: assert failed
5) test_is_threeofakind: all-tests.c:129: assert failed
6) test_is_straight: all-tests.c:136: assert failed
7) test_is_fullhouse: all-tests.c:146: assert failed
8) test_is_flush: all-tests.c:152: assert failed
9) test_is_straightflush: all-tests.c:159: assert failed
10) test_is_fourofakind: all-tests.c:167: assert failed
11) test_is_royalflush: all-tests.c:173: assert failed
12) test_compare_hands: all-tests.c:177: expected <1> but was <0>
13) test_compare_highcards: all-tests.c:185: expected <1> but was <0>
!!!FAILURES!!!
Runs: 15 Passes: 2 Fails: 13
Which tells you that, of the 15 unit tests, 13 failed.
A good way to ensure you're on the right track, besides reading and understanding the problem description thoroughly, is to scan through the unit test implementations so that you know what you need to do to pass them.
My recommendation is to simply tackle the unit tests one at a time (in the order they are given), and get each of your functions to pass its associated test. Ideally, when all your functions pass, you're good to go! (Unfortunately, it's possible that there are some edge cases that aren't tested, so you might have some additional head-scratching to do).
Testing on an Input File
After you've gotten all your unit tests to pass, you should move on to running
your program on the batch of 1000 poker games provided in the poker.txt
file. Doing this is easy, as we've already implemented the main function in
the file main.c to load the input file and run your functions on each game. To
compile this code, use the command make. If this succeeds, use the command
./poker to run the executable on the input file. You should get output like
this:
1: 8C TS KC 9H 4S vs. 7D 2S 5D 3S AC; P2 wins!
2: 5C AD 5D AC 9C vs. 7C 5H 8D TD KS; P2 wins!
3: 3H 7H 6S KC JS vs. QH TD JC 2D 8S; P2 wins!
4: TH 8H 5C QS TC vs. 9H 4D JC KS JS; P2 wins!
...
997: AD 3D TS KS 7H vs. JH 2D JS QD AC; P2 wins!
998: 9C JD 7C 6D TC vs. 6H 6C JC 3D 3S; P2 wins!
999: QC KC 3S JC KD vs. 2C 8D AH QS TS; P2 wins!
1000: AS KD 3D JD 8H vs. 7C 8C 5C QD 6C; P2 wins!
Summary: P1 (0 wins) vs. P2 (1000 wins)
Naturally, your results will depend on the implementation of the functions you previously wrote (and tested).
We highly recommend that you read through main.c to see how it works, but
please don't change the format of its output — doing so will mess up
our grading script!
We're not telling you what the correct answer is, but then again, it's not
particularly hard to discover. You can register at Project
Euler, for instance, and
check your answer there, or you can even compare your results against those of
other students (we suggest learning to use the
diff command line tool, if you want
to do this).
Have fun!
Grading
This lab is worth a total of 30 points. Points will be allotted as follows:
15 points: Unit tests
- One point for passing each successfully. Note that we use the original test suite to evaluate your work, regardless of any changes you might commit to your own unit test files.
15 points: Input file evaluation
For how many games you get right — the number of points lost is computed with the formula
,
where w is the number of games for which you guess the
wrong outcome.E.g., guessing 50 (of 1000) wrong, loses you floor(2.442) = 5 points.
Please keep in mind that if your code doesn't build for whatever reason, you will receive 0 points. We will not make any attempt to fix compilation errors for you!
Submission
Commit all changed files (git commit -a) if you haven't yet, then push your commits to BitBucket (git push). If the push fails, you may need to first pull feedback files we left for you (git pull), then try pushing again.
Keep in mind that you can push as often as you like before the deadline. We will ignore all pushes after that when grading this lab unless you let us know explicitly that you are pushing a late submission (via e-mail, ideally).
Labs are graded manually, so you will not be receiving any sort of automated response to your submission.
Note that all future labs are submitted in the same way, so this'll be the last writeup to include instructions of this nature.