Informatics 42 • Winter 2012 • David G. Kay • UC Irvine

Lab Assignment A
"Luck, Be a Lady Tonight"

This assignment is due at the end of lab on Wednesday, January 25. This is enough time for a novice Python programmer to complete the task, bearing in mind that Informatics 42 is a six-unit course that typically will require work outside of the normally scheduled lab hours.

You will also notice that the specifications for most assignments in this course are longer than we've seen before. This is a good thing: the more explanation we give, the more guidance you have. But technical specifications are not like novels. You cannot speed-read through them just one time and expect to gain the information you need. Plan to read the specifications carefully, and plan to go back and read them again to pick up additional details.

We expect you to complete this assignment in pairs, following the usual pair programming guidelines. You may not choose this project as your one "pair programming holiday" this quarter. There are lots of little details to get through, and it's really hard to do it alone. We suggest that you try to pick a partner whose experience level is relatively close to your own; that seems to optimize both the effectiveness and the efficiency of both partners' learning (i.e., you'll learn more with less effort).

Problem synopsis: Write a program to play the dice game "craps," including playing against the computer, compiling statistics on the fairness of the dice, and handling bets.

This assignment is divided into four stages. Each succeeding stage is built upon what you have already written for the previous stage. We expect you to design, write, and test this program according to these stages—first get the first-stage program working, then modify it to satisfy the second stage, and so on.

You should make sure that each stage is entirely correct and working perfectly before you go on to the next. As you complete each stage, you must demonstrate briefly to your TA or tutor that it works correctly before you go on to the following stage. If you try to add the second-stage features before your first stage is debugged, you'll just have twice as large a program to search through for errors. In fact, breaking up the problem into several subprograms will speed up your coding, aid you in debugging, and keep you from getting too far off on the wrong track. Sometimes students think, "Yes, this business about stages would be a nice idea if I had the time, but it'll take me too long." This is wrong. What will take you the most time (and thus cause you the most frustration and unhappiness) is trying to debug the whole program at once. If it seems longer to do it by stages, it's only because each stage is a nicely manageable piece that's not too taxing by itself.

You will find that this program focuses mostly on control structures—how to get the right things to happen in the right order, including managing interactions with the user. These are skills you need to program in languages like Python. But you won't find that object-oriented design, model-view-controller organization, or even unit testing will help you all that much. You should certainly try to isolate separate functionality (like rolling two dice and returning the result) into separate functions, but the interactive nature of the program and the randomness of the dice will lead you simply to run interactive tests as frequently as you can.

Grading: Your score will depend primarily on correctness and on adherence to the specifications (which is essentially the same thing). It is always far better to implement a subset of the functionality correctly than to attempt to implement more features in a program that retains some bugs. Secondary aspects of your score will include contract and purpose information where appropriate, reasonable adherence to Python coding conventions and idioms, and avoidance of grossly clumsy or stylistically poor code.

In assignments for this class, code that doesn't compile correctly will receive very little credit, no matter how long or how hard you worked on it. If it doesn't compile, there's no real way to tell what it does or doesn't do.

Statement of the problem: The operators of the oldest established permanent floating crap game in New York have decided to computerize their racket, figuring that since a computer can shoot craps faster than a human, more games can be played, so more money can be made. Sky Masterson has fingered you to write the program.

Craps is a game played with two six-sided dice; each die's faces are numbered from 1 to 6. The player (or "shooter") rolls the dice. The shooter wins right away If the total of the two faces is a "natural" (7 or 11). If it is "craps" (2, 3, or 12), the shooter loses. Anything else becomes the shooter's "point". The shooter then keeps on rolling until either winning by "making the point" (i.e., rolling that number again) or losing by "crapping out" (rolling a 7). (The rolls 2, 3, 11, and 12 have no special meaning when the shooter is trying to make the point.)

Stage I: In this stage you will write an interactive program to play a single game of craps. When you complete this stage, it should produce sample sessions like the following:

Welcome to Sky Masterson's Craps Game 

Roll is  7
Natural; shooter wins
Thank you for playing
Another possible session is:
Welcome to Sky Masterson's Craps Game 

Roll is  6
The point is 6
Roll is  12
Roll is  12
Roll is  4
Roll is  10
Roll is  7
Crapped out; shooter loses
Thank you for playing

Use your reference materials (the online Python documentation or the textbook) to find out how to generate random numbers. Often we'll just tell you specific details like this, but you do need the experience of looking things up yourself and this is an easy thing to find. (But if it takes you more than ten minutes, ask someone rather than spending more time on it.)

Stage II: [Make your enhancements for this stage on a separate copy of your Stage I program. Don't modify your only copy.]

For this stage, modify your program so that it plays a succession of games, continuing until the player asks to quit, and alternating games played between the human player and the computer. That is, after the human player plays a single game (as described in Stage I), the computer will roll dice for a game. Then, your program should ask the player if he would like to play another round. If the answer is yes, then the whole process is repeated. If not, the program prints its final message and halts, as before.

A sample session for this stage follows; the user's input is shown in bold face.

Welcome to Sky Masterson's Craps Game 

Your game:
Roll is  7
Natural; shooter wins

Computer's game:
Roll is  3
Craps; shooter loses

Would you like to play again? (y or n):  y
Your game:
Roll is  3
Craps; shooter loses

Computer's game:
Roll is  8
The point is 8
Roll is  7
Crapped out; shooter loses

Would you like to play again? (y or n):  y
Your game:
Roll is  6
The point is 6
Roll is  8
Roll is  11
Roll is  10
Roll is  5
Roll is  7
Crapped out; shooter loses

Computer's game:
Roll is  8
The point is 8
Roll is  6
Roll is  10
Roll is  4
Roll is  8
Made the point; shooter wins

Would you like to play again? (y or n):  n
Thank you for playing

Stage III: Sky doesn't trust you completely, though; he's afraid you might make the game crooked so a pal of yours can beat the odds. In this stage you will demonstrate that the dice aren't loaded (i.e., that the roll function is pretty random). Modify your program so that it keeps track of the number of times each possible total (2 through 12) comes up during the entire session.

After the player decides to stop playing, continue rolling silently until you have exactly 2000 rolls. Then plot the results in histogram form, showing how frequently each possible two-dice total (2 through 12) came up. Your results might look like this:

Welcome to Sky Masterson's Craps Game

Your game:
Roll is  2
Craps; shooter loses

Computer's game:
Roll is  10
The point is 10
Roll is  5
Roll is  10
Made the point; shooter wins

Would you like to play again? (y or n):  n

Thank you for playing

Distribution of dice rolls

 2:    54 ( 2%)  **
 3:   118 ( 5%)  *****
 4:   164 ( 8%)  ********
 5:   228 (11%)  ***********
 6:   253 (12%)  ************
 7:   333 (16%)  ****************
 8:   284 (14%)  **************
 9:   227 (11%)  ***********
10:   157 ( 7%)  *******
11:   116 ( 5%)  *****
12:    66 ( 3%)  ***

Stage IV: We expect that every pair will be able to complete this final stage; similar students in similar classes in the past have done it (singly). But if your pair runs into unusual difficulty on this stage, you should know that you can get a reasonable score on the assignment without it (assuming that what you do turn in is entirely correct).

In this stage you will add betting to the game. Initially, the player and the computer are both given $500. The program will play a series of games, alternating turns between the human player and the computer, just as in Stage II. The program ends either when the player doesn't want to play any more (as before) or when the player runs out of money (goes broke). When play is over, the program will print betting statistics (described below) before printing its final message and ending.

The computer, unlike the human player, has infinite credit; its funds can go below zero without affecting the play. But neither player may make a negative bet.

Before the human player's turn starts, the program asks how much the player wants to bet. And if the human player needs to roll to make a point, the program will ask before each roll how much more to add to the current bet. If the player tries to bet more money than he or she has, the program will print a message and ask for another amount.

When it is the human player's turn, the computer will simply match the human player's bet.

When it is the computer's turn, the computer will bet half of its current funds or $75, whichever is lower. But if the computer is in debt or broke, it will bet $15. The amount of the computer's bet is displayed, and the player will be asked to make a bet. The most the player can bet is the amount the computer bet or the amount the player has, whichever is lower. If the player attempts to bet more than he or she has, handle it as above. If the player bets more than the computer bet, the program lowers the player's bet to match. If the player bets less than the computer, the computer will reduce its bet to match the player's bet. After these initial bets, no other betting occurs during the computer's turn.

Finally, your program should also keep track of some statistics and print them out at the end of the entire session. Keep track of how much each player (human and computer) has bet and has won, and how much they have left at the end. Also, keep track of the smallest and largest pot of the game and the average pot size.

Here is a sample session for this stage:

Welcome to Sky Masterson's Craps Game

Your game:
How much would you like to bet?  100
Roll is  10
The point is 10
How much would you like to bet?  300
Roll is  9
How much would you like to bet?  50
Roll is  8
How much would you like to bet?  100
Sorry; you've already bet $450.00 and you can't bet more than the $50.00 you have left.
How much would you like to bet?  0
Roll is  8
How much would you like to bet?  0
Roll is  2
How much would you like to bet?  0
Roll is  9
How much would you like to bet?  0
Roll is  10
Made the point; shooter wins

You have $950.00; computer has $50.00.

Computer's game:
Computer bets $25.00
How much would you like to bet?  100
You can't bet more than the computer; bet changed to $25.00.
Roll is  6
The point is 6
Roll is  10
Roll is  11
Roll is  6
Made the point; shooter wins

You have $925.00; computer has $75.00.
Would you like to play again? (y or n):  y

Your game:
How much would you like to bet?  500
Roll is  7
Natural; shooter wins

You have $1425.00; computer has $-425.00.

Computer's game:
Computer bets $15.00
How much would you like to bet?  15
Roll is  8
The point is 8
Roll is  7
Crapped out; shooter loses

You have $1440.00; computer has $-440.00.
Would you like to play again? (y or n):  n

Final game statistics

        Total amount bet        Total amount won        Final balance
You               990.00                 1930.00              1440.00
Computer          990.00                   50.00              -440.00

Smallest pot of game: $   30.00
Largest pot of game:  $ 1000.00
Average pot value:    $  495.00

Thank you for playing

Distribution of dice rolls

 2:    70 ( 3%)  ***
 3:   120 ( 6%)  ******
 4:   151 ( 7%)  *******
 5:   218 (10%)  **********
 6:   266 (13%)  *************
 7:   319 (15%)  ***************
 8:   289 (14%)  **************
 9:   240 (12%)  ************
10:   173 ( 8%)  ********
11:    98 ( 4%)  ****
12:    56 ( 2%)  **

How to get started: Read the assignment specification. Reading it through twice wouldn't hurt.

It is absolutely essential that you work in very small increments. After each tiny change, run your code to make sure it behaves correctly. Novice programmers (and even some experienced ones) sometimes fall into this terrible trap: They add a whole lot of code to their program all at once, then they try to run it, and their code doesn't even compile correctly. The debugging job is enormous at that point, because there's no easy way to tell which part of the code has the error in it. When you add one tiny portion of code at a time, rerunning after each addition and not adding more until what you have is correct, your overall development time is shorter because you can locate any error in the small part of code you most recently added. (For a non-computing-related illustration of how it's better to take small, easy steps rather than trying to bite off a lot at once, everyone should read Atul Gawande's article about ICU checklists.)

Keep adding new functionality, small piece by small piece, running and testing as you go, until you've satisfied all the requirements in the assignment specification. When you have a way to approach a task, it's less daunting.

Here's one more hint: As you add functionality, add extra print statements that print out the values of variables that are changing. That way you can see the progress (correct or otherwise) of your computations. Even if you'll remove those statements once you're sure the code works, having them during development is helpful.

What to turn in: Turn in via Checkmate one Python source code (.py) file containing all your code for the final version you completed. If you haven't registered yourself for Checkmate this quarter, do it now; instructions are on the syllabus. As usual, each pair should submit just one solution, with both partners' names clearly listed at the top of each file.

Also as usual, every student must fill out a partner evaluation form at eee.uci.edu. You can get to the partner evaluation for this lab by logging in at eee.uci.edu, choosing MyEEE, and selecting Survey. Your class participation score will suffer if you neglect to do this. We have not turned on the Email nagging option for this evaluation; it's up to you to remember to do it within a day or so of the due date.

Original concept (and references to the musical Guys and Dolls) by David A. Smallberg. Rewritten by David G. Kay, September 1985. Modified for use in ICS 21 by David G. Kay, October 1990. Revised by Norman Jacobson, Winter 1991. Minor revisions by Norman Jacobson, Fall 1991, by David G. Kay, Winter 1992, by Norman Jacobson, Fall 1992, and by David G. Kay, Winter 1993. Revised for Python and Informatic 42 by David G. Kay, Winter 2012.