CS21 Lab 4: while loops and functions

Due Saturday, February 23, before midnight.


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

  $ update21
  $ cd ~/cs21/labs/04

Programming Tips

Topics for this assignment


A Game of 21 Stones

Alice and Bob are life-long rivals and have agreed to meet and decide once and for all who is the best ever.

To test their wits, determination, and awesomeness, they have agreed to play The Game of 21 Stones.

This game begins with a pile of 21 stones. Alice and Bob take turns. Each turn, a player may take either one, two or three stones. They must take at least one stone, and cannot take more than three stones. The player who takes the final stone loses the game and will never be able to program in Python ever again.

Which player has the wits and determiniation to win? Who will be awesome enough to conquer the Game of 21 Stones?


For this lab assignment, you will implement functions to play the Game of 21 Stones. To help you build this program, we have broken the design into several parts. Please read through the entire writeup before starting.

The first few questions will ask you to implement the following:

The first three questions ask you to write a single function outside the context where they should be used. To test them, you will call them from main() using test values. Testing functions with known inputs and outputs is called unit testing. If you know a unit test doesn't produce the correct output, you know there is a bug in the function!

1. Is the game over?

Complete the program gameOver.py that takes a number of stones as input and returns True if and only if the game is over; i.e., if the given number of stones equals zero.

isGameOver

To test, call isGameOver(stones) from main() for several different values of stones. Print the result of each call to isGameOver Try to make sure isGameOver(stones) works for any integer input.

  $ python3 gameOver.py
  isGameOver(3)? NO
  isGameOver(0)? YES
  isGameOver(9)? NO

2. Who is the next player?

Complete the program nextTurn.py that tests the following function:

nextTurn

To test, call nextTurn from main() with the values "Alice" and "Bob"

  $ python3 nextTurn.py
  When it is Alice's turn, the next player to take a turn is: Bob
  When it is Bob's turn, the next player to take a turn is: Alice

3. How many stones do you want to take?

Complete the program getChoice.py asks how many stones a player wants to take. The player must take at least one stone and can take at most three, but cannot take more stones than are left. If the user enters an invalid number of stones, your program should print a helpful error message and ask the user again.

Implement a function getChoice to ask the user for their decision.

getChoice

To test, call getChoice(...) from main() several times on different inputs, each time printing the chosen number of stones.

  $ python3 getChoice.py
  Alice, it is your turn.
  There are 21 stones left.  How many stones will you take?  9
  Alice, you cannot take more than 3 stones.
  There are 21 stones left.  How many stones will you take?  0
  Alice you must take at least one stone.
  There are 21 stones left.  How many stones will you take?  3
  Alice took 3 stones.

  Bob, it is your turn.
  There are 2 stones left.  How many stones will you take?  3
  Bob, you cannot take more than 2 stones.
  There are 2 stones left.  How many stones will you take?  0
  Bob you must take at least one stone.
  There are 2 stones left.  How many stones will you take?  1
  Bob took 1 stones.

  Alice, it is your turn.
  There are 1 stones left.  How many stones will you take?  2
  Alice, you cannot take more than 1 stones.
  There are 1 stones left.  How many stones will you take?  0
  Alice you must take at least one stone.
  There are 1 stones left.  How many stones will you take?  1
  Alice took 1 stones.

4. Putting it all together

Write a program twentyOneStones.py that implements the full Game of 21 Stones. In previous parts of this assignment, you implemented isGameOver, nextTurn, and getChoice functions. Copy them over to twentyOneStones.py.

Write a main() function which implements a game loop. In main() you should keep track of the current player and the number of remaining stones. The game loop should quit when isGameOver returns True. Each turn, the current player should choose a legal number of stones. Those stones should be removed from the pile of remaining stones, and the current player should be updated using nextTurn.

To test your program, play the game! You should test the game by playing multiple times. Make sure you can replicate the output below.

$ python3 twentyOneStones.py 
Welcome to the Game of 21 Stones!

Alice, it is your turn.
There are 21 stones left.  How many stones will you take?  3

Bob, it is your turn.
There are 18 stones left.  How many stones will you take?  9
Bob, you cannot take more than 3 stones.
There are 18 stones left.  How many stones will you take?  0
Bob you must take at least one stone.
There are 18 stones left.  How many stones will you take?  3

Alice, it is your turn.
There are 15 stones left.  How many stones will you take?  2

Bob, it is your turn.
There are 13 stones left.  How many stones will you take?  5
Bob, you cannot take more than 3 stones.
There are 13 stones left.  How many stones will you take?  3

Alice, it is your turn.
There are 10 stones left.  How many stones will you take?  3

Bob, it is your turn.
There are 7 stones left.  How many stones will you take?  3

Alice, it is your turn.
There are 4 stones left.  How many stones will you take?  2

Bob, it is your turn.
There are 2 stones left.  How many stones will you take?  3
Bob, you cannot take more than 2 stones.
There are 2 stones left.  How many stones will you take?  0
Bob you must take at least one stone.
There are 2 stones left.  How many stones will you take?  1

Alice, it is your turn.
There are 1 stones left.  How many stones will you take?  2
Alice, you cannot take more than 1 stones.
There are 1 stones left.  How many stones will you take?  1

No more stones remain!
Alice took the last stone.  Alice LOST.
Bob wins.  Bob is the AWESOMEST.

(Extra Challenge) 5. Generalizing the game.

There are many ways to extend this game. The game as described has the following "state":

In a new file extendedStones.py generalize the Game of 21 Stones by asking the user for either the initial number of stones or the maximum number of stones a player can take. You could also modify the game by allowing the user to choose how many players and/or what their names are.

The Game of 21 Stones is an example of a general class of games called NIM. Check out the wikipedia article for more ideas on how to extend the game.


6. Answer the Questionnaire

Each lab has 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.


Turning in Your Labs

Don't forget 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.