CSC 209H: Assignment 3

Weight: 10% of course grade.

Due date: 10:00 p.m. Monday, July 24


Introduction

In this assignment, you will be writing programs that will play the game of Blackjack.

Also known as Twenty-One, the game itself is quite simple. The goal of the game is to take cards to get as close to the total of twenty-one as possible, without going over. Cards 2 through 10 are worth their face value, while jacks, queens and kings (face cards) are worth 10. An ace can be counted either as 1 or 11.

Blackjack is played between a number of players and the dealer. Each player competes only against the dealer (and not against each other). The player wins if the player's hand is closer to 21 (without going over) than the dealer's hand. If a hand totals more than 21, that player (or dealer) is said to bust, which is an automatic loss.

A "blackjack" is a two-card hand consisting of an ace and a ten-value card (not necessarily a jack). A blackjack is an automatic winner, unless both the player and the dealer hold blackjacks, which is a tie.

Rules

For this assignment, we'll simplify some of the rules of blackjack from what is typically played in casinos. In each round, each player is dealt two cards face-up, and the dealer is dealt one face-up card and one card face-down (the "hole" card). Each player, in sequential order, gets to play his hand. If the player's current hand totals less than 21, the player may choose to either HIT (add another card to his hand) or STAND (take no more cards). If a player hits and the total is over 21 (remember, an ace may count as either 11 or 1), the player has busted and loses.

Once all players have either busted or chosen to stand, the dealer plays. The dealer reveals the hole card, and draws cards until the hand totals 17 or more. (So, the dealer hits on anything less than 17, but stands on 17 or more.)

If the dealer busts, all non-busted players win. If the dealer does not bust, the dealer's hand is compared to each non-busted player's hand. If the player's total is greater than the dealer's total, that player wins. If the dealer's total is greater than the player's total, the player loses. If the player's hand and the dealer's hand have the same total, it is a "push" or tie (unless one of the hands is a blackjack). A blackjack beats anything except another blackjack.

Betting

Blackjack is inherently a gambling game, so we'll need to handle betting. Prior to each round, each player makes a bet (an integer). The minimum bet will be 1 chip. If the player loses the hand, the bet is lost. If the player ties the dealer, the player gets the bet back. If the player wins (without a blackjack), the player gets the bet back plus the value of the bet (so, on a bet of 2 chips, the player would win 2 additional chips for a total of 4). If the player wins with a blackjack, the player is paid 3:2, rounded down to an integer (so, on a bet of 2 chips, the player would win 3 additional chips).

(For the pros: no splitting, double-down, surrender, insurance, or any other such rules for this assignment.)

Cards

Cards will be represented externally as two characters: the rank of the card and its suit. The first character will be one of 2,3,4,5,6,7,8,9,T,J,Q,K,A (for ten, jack, queen, king and ace). The second character will be one of C,D,H,S (for clubs, diamonds, hearts and spades).

Internally, you may represent a card in any way you wish. Suits are not used in blackjack, so you may freely ignore them. Some functions in utils.c might be useful, and can entirely take care of handling cards for you.


Part 1 - bjplayer

In this part you are asked to write a C program that will play blackjack. There is no requirement that your program wins any hands! Your program need only play according to the rules specified here.

Your program will be named bjplayer. You will also submit a README text file briefly describing how your program works. Be sure to point out any interesting strategies you might be using!

Your program will be executed with the following arguments:

$ bjplayer num_players num_rounds num_decks chips

All command line arguments are mandatory.

Your program will read from stdin and write to stdout. It will iteratively execute the following phases:

When EOF is encountered on stdin instead of reading the initial hands, your program should terminate normally. If the player is reduced to zero chips, the program should terminate normally.

Each program may assume it is playing a series of games with a single shuffle. A particularly clever program may count played cards and change its bet or its behaviour if the cards remaining in the deck are favorable.

Warning: you will not be evaluated on how clever your program is, only that it follows the specification! Do not spend so much time on your player so that you do not complete the rest of the assignment!

Tip: To aid in debugging (particularly for part 2), you might want to send diagnostic or status information to standard error. Be sure to turn off this diagnostic output before handing in your assignment.

Example

The following may be an execution of such a program.

stdin	  stdout
	  1
4C,6S|6H  HIT
QH	  STAND
WIN
6H,8S,JD

The player is playing a single hand, and wins the hand since the dealer busts. The player would win one additional chip (if the player began with just one chip remaining, the player would have two chips after this hand).

Hints and Clarifications


Part 2 - bjdealer

In this part you will write a C program named bjdealer that will act as the dealer in a game of blackjack. The competitors will be executions of bjplayer programs.

Your program should support being run in the following manner:

$ bjdealer [-s random_seed] num_rounds num_decks chips list-of-players

Following the -s option (if it exists) is an unsigned long integer N, the seed to the pseudo-random number generator (you may wish to use strtoul() to convert the argument to an unsigned long). If -s does not appear, the generator should be seeded from /dev/urandom (functions in utils.c might help).

The remaining arguments are mandatory. The num_rounds specifies the number of rounds to play, and must be greater than 0. The num_decks is the number of standard decks to play with, and must be between 2 and 8. The chips is the number of chips every player starts with, and must be greater than 0.

The list-of-players will be a list of path names of bjplayer programs, possibly (and probably) with duplicates. For example, a list might be bjplayer bjp2 ../other/bjplayer bjplayer bjplayer for a game with 5 players. There must be at least 1 player specified, and no more than 8 players.

Your program will do the following:

The playing deck is shuffled once at the start of play, and the top card is drawn from the deck each time a card is needed. The deck is typically not reshuffled between rounds, nor are cards returned to the deck once they have been used. If, however, before a round begins there are strictly less than 52 cards remaining in the playing deck, all cards are collected and the playing deck is reshuffled (just as at the beginning of play). To indicate this in-play shuffle to the players, the dealer sends a SIGUSR1 signal to each player process. The player program must handle this signal, as the default signal action is termination.

The bjdealer program must communicate with its child processes using pipes. In the case that a player ceases to execute (or otherwise closes the pipe), your bjdealer program should forevermore ignore that player (cards may still be dealt if you wish, but your program should not wait for any further responses).

[Update 23 Jul 2006] Once the specified number of rounds have been played (or all players have gone broke), your dealer program should print a report of how many chips each player ends with. The following is one such report:

Game outcome:
Player 1 is broke!
Player 2 finished the game with 2 chips

Important: Be sure to clean up any processes that may be left behind before logging out of your machine. The ps and top commands can help you find any lingering processes.

Hints and Clarifications


Learning Objectives

What to hand in

You will commit to the a3 directory of your CSC209 repository the following files:

You are strongly encouraged to take advantage of the version control system and commit your work frequently so that you can keep track of your progress. Please note that perfectly fine (and even recommended) that you keep any additional files related to this assignment (such as files and scripts used for testing) under version control. The markers will simply ignore such files.