CIT 591 Assignment 3: Opening bid in Bridge
Fall 2011, David Matuszek

# Purposes of this assignment

• To get you started with unit testing
• To get you started with pair programming
• To emphasize the value of small functions

# General idea of the assignment

Contract Bridge is a card game in which the players bid to see who gets to play first. It has evolved some fairly complex rules for how to bid. In this assignment, you will write a program that decides what to bid. This program determines only the first, or "opening" bid; later bids are beyond the scope of this assignment.

You do not need to know how to play Bridge in order to write this program. I will tell you everything you need to know about Bridge. The rules that I give for making the opening bid are basically the system invented by Charles Goren, with minor modifications by others. Understand this: If you know a different set of rules, forget them, because your program will be graded on whether it follows my rules, which are slightly simplified (for instance, I ignore "quick tricks").

## The cards

There are 52 cards in a Bridge deck. Every card has a value (`2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `Jack`, `Queen`, `King`, or `Ace`) and a suit (`Club`, `Diamond`, `Heart`, or `Spade`). The suits are ranked: Clubs < Diamonds < Hearts < Spades. Clubs and Diamonds are the minor suits; Hearts and Spades are the major suits. The Jack, Queen, King, and Ace are called face cards. A hand consists of 13 cards randomly chosen from a deck.

We will use the following abbreviations: `C`=Clubs, `D`=Diamonds, `H`=Hearts, `S`=Spades, `J`=Jack, `Q`=Queen, `K`=King, and `A`=Ace. An individual card will be represented by its value followed by its suit, for example, `'6H'` represents the 6 of Hearts. For convenience in typing out a hand, we will represent it as a string of 13 cards separated by spaces, for example, `'5C 7H AS JD 9D 2C KH 10H 4C 8H 8C AD 10C'`. [However, this is only convenient for people, not for programs. I strongly recommend that you have a function to convert this to a different representation, maybe a list of tuples or something like that.]

A bid will be represented by a string consisting of a count 1 to 7, and a trump suit, which may be one of the four suits or the special No Trump bid, abbreviated `NT`, meaning no particular suit. So some legal bids might be `'1S'`, `'5H'`, or `'3NT'`. For about half the hands there will be no good opening bid, and in these cases your program should return a bid of `None`--that is, the special Python value `None`, not the string `'None'`.

Determining the opening bid proceeds in two stages. First, you need to count the number of points in the hand. Second, you use this point count along with the distribution (how many of each suit there are) to decide the opening bid.

## Counting points

The point count of a hand is the number of high card points, plus the number of distribution points.

High card points: Each Ace counts 4 points; each King counts 3 points; each Queen counts 2 points; and each Jack counts 1 point. For example, the hand given above contains `AS`, `JD`, `KH`, and `AD`, which is `4+1+3+4=12` points.

Distribution points: If you have more than 4 cards in any suit, count 1 point for each additional card. The sample hand above has 5 Clubs, 3 Diamonds, 4 Hearts, and 1 Spade, so add 1 distribution point for the Clubs, making the total point count `13`.

A hand is balanced if it contains at least two cards and not more than four cards in every suit. As a special case, a hand that has 5 cards in a minor suit, with 3, 3, and 2 cards in the other suits, is also considered balanced.

## Bidding

The following is slightly adapted from http://www.cs.cmu.edu/~hde/bidding.htm:

Your program should bid as follows:

• `1NT`: Exactly 16-18 high card points, a balanced hand (4-3-3-3, 4-4-3-2, or 5-3-3-2 where the 5 cards are in a minor suit).
• `1H` or `1S`: 13-21 points and 5 or more cards in Hearts or Spades (bid the longer suit; if you have two five-card suits, bid the higher-ranking suit.)
• `1C` or `1D`: 13-21 points (bid whichever of Clubs or Diamonds is the longer suit; if equal in length, bid Clubs).
• `1C` or `1D`: A balanced hand with 19-20 high card points. Bid the longest minor suit, even if it's only 3 cards. (With 3-3 in minors bid `1C`; with 4-4 or higher bid `1D`.)
• `2NT`: Exactly 21-23 high card points and a balanced hand (4-3-3-3, 4-4-3-2, or 5-3-3-2 where the 5 cards are in a minor suit).
• 2 of a suit: A very strong hand (22+ points) with 5 or more cards in some suit (bid that suit).
• If you have 5 or more cards in two different suits:
• If one is a major suit and the other isn't, bid 2 of the major suit; otherwise,
• If one suit has more high-card points, bid 2 of that suit; otherwise,
• If one suit is longer, bid 2 of that suit; otherwise,
• Bid 2 of the lower ranking suit.
• 3 of a suit: Preemptive: a weak hand (5-9 high card points) with a 7-card suit (bid that suit).
• 4 of a suit: Preemptive: 6-108 high card points with an 8-card suit (bid that suit).
• `None` in all other cases.
• I don't think there are cases where more than one of the above rules applies; but if there are, use the first rule that applies.

## Required functions

You must have the following three functions. For each function, the parameter `hand` is a string containing the abbreviated names of 13 cards, separated by spaces.

`def highCardPoints(hand)`
Returns, as an integer, the high card count for this hand.
`def distributionPoints(hand)`
Returns, as an integer, the distribution count for this hand.
`def openingBid(hand)`
Returns the opening bid as a two- or three-character string, or the special "non-value" `None`.

We will be running our own unit tests on your program, and if we can't call the above functions and get the right kind of result, you may lose lots of points. So spell the function names correctly, get the capitalization right, and be sure you know what to expect as a parameter and what to return as a result.

## Other functions...and TDD

There are lots of little things to check in this assignment, so you should write lots of little functions.

Use Test Driven Design. When you look at what needs to be done, you probably won't know where to start. Start by writing a test! The test will tell you what the function is supposed to do. Then you can write the function.

Every function (including the three required functions) must have at least one test for it. So you might as well try to do things in the recommended order--that is, write the test first, then write the function.

You do not need a `main` function, and you should not do any input or output (except to help you in debugging, then remove it before you submit the program). This isn't a complete program, it's a set of functions that could be used by a bridge playing program.

## Notes for pair programming

Pair programming is best done sitting together at one computer. If you can, come in together and work in the lab--or in a lounge, or anyplace you can get together with your partner.

Many of you won't be able to do this after the lab ends. Exchange email addresses, and do your best to share code, read each other's code, and work cooperatively. You probably use some chat program with friends; use it here.

One program that looks like it may be very helpful is EtherPad. I haven't recommended this program to classes before, so if you try it, please let me know how it works out. Since it is designed for sharing plain text, I think it may be better for pair programming than, say, Google Docs.

In the past, some students have tried splitting up the work by having one person write the tests and the other person write the functions. In every case, this has ended badly. Learn from their experience: Don't try this!

Each program is worth 100 points, unless otherwise specified. Grading will be based on correctness, style, and useability.

• Correctness: The program produces correct answers and does what the assignment says to do and does not crash.
• Style: The program has good names for variables and functions, proper spacing and indentation, good documentation, etc.
• Every function should have a name that tells you what it does.
• Every function should have a documentation string that tells in more detail what the function does.
• Every variable should have a name that tells you what it holds.
• Avoid abbreviations--long names are okay.
• Very long lines (> 79 characters) should be avoided. Often you can make a line shorter by taking out a subexpression and assigning it to a variable.
• Functions should be short and single purpose. (There's nothing wrong with having a function that does nothing other than call a couple of other functions.)
• Avoid global variables.
• Useability: It should be easy to figure out how to use your program.
• In this case, just make sure you have correctly defined the three required functions.

# Due date

Submit your team's program, as a single `.zip` file, to Sakai, by 6am next Friday, September 30. Decide which of you is going to turn in the assignment, and make only one submission for the two of you. Make sure both of your names are in comments at the top of each file.