CS21 Lab 4: While loops and functions

Due Saturday, February 27, before midnight (US/Eastern local to Swarthmore)

Programming Tips

As you write your first programs, start using good programming practices now:

  • Use a comment at the top of the file to describe the purpose of the program (see example).

  • All programs should have a main() function (see example).

  • Use variable names that describe the contents of the variables.

  • Write your programs incrementally and test them as you go. This is really crucial to success: don’t write lots of code and then test it all at once! Write a little code, make sure it works, then add some more and test it again.

  • Don’t assume that if your program passes the sample tests we provide that it is completely correct. Come up with your own test cases and verify that the program is producing the right output on them.

  • Avoid writing any lines of code that exceed 80 columns. In emacs, at the bottom, center of the window, there is an indication of both the line and the column of the cursor.

Function Comments

All functions should have a top-level comment! Please see our function example page if you are confused about writing function comments.

Are your files in the correct place?

Make sure all programs are saved to your cs21/labs/04 directory! Files outside that directory will not be graded.

$ update21
$ cd ~/cs21/labs/04
$ pwd
/home/username/cs21/labs/04
$ ls
Questions-04.txt
(should see your program files here)

Goals

  • Write programs with multiple functions.

  • Solve problems using indefinite while loops.

  • Learn to use the random library to make pseudo-random choices.

checkpoint

At the end of your lab session, be sure to run handin21.

Your lab instructor will check your files, which should reflect that you have made non-trivial progress (in python or pseudocode) towards the solution. Note that if you have not made much progress towards your solution, we expect that you would have been actively seeking help during your lab over Slack.

10% of your lab grade is dependent on this checkpoint.

If there are circumstances which prevent you from making substantial progress on this lab, please contact your lab instructor as soon as possible.

introduction

In this week’s lab we’re going to incrementally develop the game of Pig.

the rules of pig

Each turn, a player repeatedly rolls a die until either a 1 is rolled or the player decides to "hold":

  • If the player rolls a 1, they score nothing and it becomes the next player’s turn.

  • If the player rolls any other number, it is added to their turn total and the player’s turn continues.

  • If a player chooses to "hold", their turn total is added to their score, and it becomes the next player’s turn.

The game ends once all players have taken the same number of turns and at least one player has a score of 100 or more. The highest score wins!

modified rules adapted from: wikipedia

We will build this incrementally. As such, we’ll be modifying the main function as we move from step to step. There’s no need to save your main function from a previous step as you work on each next step. The entire lab will be written in the file pig.py.

1. roll again?

In the file named pig.py, write a function named rollAgain that asks a user to enter either "yes" or "no", and returns the string entered by the user. If the user doesn’t enter "yes" or "no", your function should print an error message, and prompt the user to try again. The function should only return when the user enters a valid string value.

The rollAgain function does not take any input values (it has no parameters), but it should return a string value. Its function definition will look like:

def rollAgain():

Your main function should make a call to the rollAgain function and print out the value returned. Here are some examples of how the program should work up to this point:

$ python3 pig.py
Do you want to roll again? yes
rollAgain returned yes

$ python3 pig.py
Do you want to roll again? Yes
Whoops! Yes isn't a valid choice. Try again.
Do you want to roll again? why didn't that work
Whoops! why didn't that work isn't a valid choice. Try again.
Do you want to roll again? nope
Whoops! nope isn't a valid choice. Try again.
Do you want to roll again? no
rollAgain returned no

Remember that python strings can be compared with relational operators like == or < just like integers and floats.

"morning" != "evening" # evaluates to True

2. play one turn

Let’s extend our program to add a function that plays one "turn" of pig.

Remember, we are solving this incrementally so there’s no need to preserve your main function as you develop the solution to this next step.

To play a round, add a new function called playerTurn. This function takes one parameter, the player’s name (a string) and returns the number of points the player earned during their turn. The function definition will look like:

def playerTurn(name):

The function should follow the rules of the game as described above:

  1. Initialize their turn total to 0 points

  2. Roll the die and print the result.

  3. If the player rolled a 1, their turn total is set to 0, print an appropriate message, and their turn ends

  4. If the player rolled any other number, the turn total is incremented by the value rolled and their current turn total is displayed.

  5. Ask the player if they want to roll again (using the rollAgain function)

  6. If they want to roll again, start over at step 2; otherwise their turn ends

  7. The player’s turn total is returned from the function

Note: To roll a die, use random.choice(range(1, 7)) to randomly choose a number between 1 and 6. Be sure to import random at the top of your program.

Modify your main function so that it asks the player their name and then plays one turn of pig using the playerTurn function. Print out the return value of the playerTurn function. Here are some example runs:

$ python3 pig.py
What is your name? Rich
Rich rolled a 5
Rich earned 5 points so far this turn
Do you want to roll again? yes
Rich rolled a 4
Rich earned 9 points so far this turn
Do you want to roll again? yes
Rich rolled a 5
Rich earned 14 points so far this turn
Do you want to roll again? no
playerTurn returned 14

$ python3 pig.py
What is your name? Spencer
Spencer rolled a 1
You pigged out!!
playerTurn returned 0

$ python3 pig.py
What is your name? Charlie
Charlie rolled a 2
Charlie earned 2 points so far this turn
Do you want to roll again? maybe
Whoops! maybe isn't a valid choice. Try again.
Do you want to roll again? ok
Whoops! ok isn't a valid choice. Try again.
Do you want to roll again? yes
Charlie rolled a 6
Charlie earned 8 points so far this turn
Do you want to roll again? yes
Charlie rolled a 2
Charlie earned 10 points so far this turn
Do you want to roll again? yes
Charlie rolled a 3
Charlie earned 13 points so far this turn
Do you want to roll again? yes
Charlie rolled a 1
You pigged out!!
playerTurn returned 0

3. play a game

To play a full game of pig, two players will take turns rolling until one of the players gets 100 points. Modify main to ask for the names of the two players and set their current points to 0. Then, have each player alternate taking turns using the playerTurn function until the game ends. Be sure to show the players the current scores before its their turn.

The game ends after both players have taken their turn and at least one of the players has 100 or more points. The second player always gets one last chance to tie or beat the first player, so don’t stop the game just because the first player got to 100 points. At the end of the game, show the final scores and print out the name of the winner.

The game doesn’t instantly end if one player temporarily exceeds 100 points during their turn. For example, let’s say that player 1 has 80 points and player 2 has 97 points points. It’s player 2’s turn. Player 2 rolls a 5. If player 2 stops rolling, they’d have a score of 102 and the game would end (and they would win). However, if they choose to keep rolling and eventually roll a 1, they would get no points for their turn, remain at 97 total points, and the game would continue.

If both players end their turns above 100 and they have the same number of points, it’s a tie.

TIP: When testing the program, it can be frustrating to have to play the game up to 100 every time. One way to make testing less tedious is to start each player at, say, 80 points, instead of 0. This way, the game will end more quickly and allow you to test the program more easily. Be sure you set each player back to 0 points before turning in your final program!

Below are some sample runs of the program.

4. answer the questionnaire

Each lab will have a short questionnaire at the end. Please edit the Questions-04.txt file in your cs21/labs/04 directory and answer the questions in that file.

Once you’re done with that, run handin21 again.

5. add a computer player — optional

This is an optional extra challenge. This part does not affect your grade so please only attempt this after completing the rest of your lab. It is simply an extra challenge, if you want to try it.

If you want to try it, make a copy of your program first:

$ cp pig.py extrapig.py

Replace the second player with a computer player. You can decide what the computer’s strategy is going to be. You can read up on pig to determine optimal strategies for the computer, or you can just have the computer choose its next move randomly!

Turning in your labs…​.

Remember to run handin21 to turn in your lab files! You may run handin21 as many times as you want. Each time it will turn in any new work. We recommend running handin21 after you complete each program or after you complete significant work on any one program.