CPSC 124 Introduction to Programming Fall 2006

Lab 5: Subroutines and Functions

Introduction

Subroutines and functions (subroutines with return values) are fundamental building blocks of well-designed programs. This lab gives you a chance to write a few. This lab is largely based on a lab by Stina Bridgeman.

Setup

Create a lab05 directory in your cs124 directory to hold the files for this lab.

Copy the file from /classes/f06/cs124/labs/lab05/ to your lab05 directory. This is just the TextIO.java file we've been using all along.

Exercises

Here are the exercises for this week's lab, due next Thursday. But don't wait until just before it is due to do it all! You should continue to follow the good programming style rules from lab #2. Remember to indent statements contained in 'if' statements and loops. Also, remember to comment your code and to use reasonable variable names. Note: points will be taken off for poor indentation, uncommented code, or poor variable naming.

  1. Write a subroutine named "stars" that will output a line of stars to standard output. (A star is the character "*".) The number of stars should be given as a parameter to the subroutine. For example, "stars(20)" would output:

    ********************
    
    Next, write a main() routine that reads a non-negative integer N from the user (you will need to do some error checking) and uses the stars subroutine to output N lines of stars with 1 star in the first line, 2 stars in the second line, and so on. For example, if N is 10 the output would be:
    *
    **
    ***
    ****
    *****
    ******
    *******
    ********
    *********
    **********
    

    Put both routines (main and stars) in a class called PrintStars and put this class in a file called PrintStars.java.

  2. Write a function called getRandomInt which takes two parameters, low and high, and returns a random integer between 'low' and up to and including 'high'. (e.g. calling this function with 1 for 'low' and 6 for 'high' should result in either 1, 2, 3, 4, 5, or 6) Your function should not perform any input or output. You do not need to check for error conditions such a 'low' being larger than 'high'.

    Next, write a function called rollDiceUntilSum which computes the number of times you have to roll a pair of dice until a particular sum is achieved. In order to be general-purpose, your function should accomodate dice with any number of sides. Your function should take the target sum and the number of sides for the dice as parameters, and should return the number of rolls it takes to get that sum. Use your random-number function to roll the dice. You do not have to worry about error-checking, such as if the sum is not actually attainable given the dice.

    Finally, write a main program which allows the user to enter a target sum and the number of sides the dice have, and then prints out the number of rolls it took to reach that sum. In main, you should do some error checking to make sure the inputted target sum and number of sides are both positive integers (>0).

    Put all three subroutines in a class called RollForSum and put this class in a file called RollForSum.java.

    Note: Test each function as you write it! This means writing a small main program which lets you try out each function separately. Don't just write the entire program and then wonder why it doesn't work.

  3. The game of nim is a two-player game, in which some number of beans are laid out and the players alternate turns in which a player can pick up one, two, or three beans. The winner is the player who picks up the last bean. (There are many variations on this game; perhaps you've heard of another version.)

    If you write pseudocode for this version of nim, you may end up with something like the following:

    get player 1's name from the user
    get player 2's name from the user
    get the number of beans to start with from the user
    while there are beans left
       display the number of beans remaining
       get the number of beans player 1 wants to pick up
       while player 1 has picked an invalid number of beans
          remind player 1 of the rules for picking up beans
          get the number of beans player 1 wants to pick up
       if player 1 has won the game
          print out a congratulatory message
       else
         display the number of beans remaining
         get the number of beans player 2 wants to pick up
         while player 2 has picked an invalid number of beans
            remind player 2 of the rules for picking up beans
            get the number of beans player 2 wants to pick up
         if player 2 has won the game
            print out a congratulatory message
    

    Now, you may notice that the pseudocode for player 1's turn is very similar to the pseudocode for player 2's turn - the only thing that is different is which player is playing. This should suggest creating a parameterized function which carries out one turn.

    Your task is to write a program called Nim.java which allows two players to play nim.

    You should first write a function called turn() which handles one turn - it should take the player's name and the number of beans left as parameters, and should return the number of beans the player has picked up. The function should prompt the player to enter the number of beans to pick up, and should make her keep choosing a number of beans until a valid number is picked up. In pseudocode:

       display the number of beans remaining
       get the number of beans the player wants to pick up
       while the player has picked an invalid number of beans
          remind the player of the rules for picking up beans
          get the number of beans the player wants to pick up
    

    Keep in mind that a player can't pick up more beans than are available - picking up two beans when only one is left shouldn't be allowed.

    Next, write a main program which uses your function to play a full game of nim, as specified by the pseudocode given above. Use call(s) to your take-a-turn function where appropriate.

    Output from a sample run of the program is shown below. (User input is shown in bold.) Your program's output doesn't have to match this exactly, but your output should be nicely formatted and players should always be referred to by name.

    Player 1, enter your name: Arthur
    Player 2, enter your name: Ford
    How many beans to start?  21
    Arthur, how many beans to pick up? (21 left)  3
    Ford, how many beans to pick up? (18 left)  0
    number of beans must be 1, 2, or 3
    Ford, how many beans to pick up?  2
    Arthur, how many beans to pick up? (16 left)  4
    number of beans must be 1, 2, or 3
    Arthur, how many beans to pick up?  3
    Ford, how many beans to pick up? (13 left)  2
    Arthur, how many beans to pick up? (11 left)  3
    Ford, how many beans to pick up? (8 left)  2
    Arthur, how many beans to pick up? (6 left)  2
    Ford, how many beans to pick up? (4 left)  2
    Arthur, how many beans to pick up? (2 left)  3
    can't pick up more beans than are left
    Arthur, how many beans to pick up?  2
    Arthur, you win!
    

    In Nim, the first player that picks beans can always win (like Tic Tac Toe). As an exercise, see if you can figure out why.

  4. Create a new version of nim called Nim2.java - leave your solution to problem #3 intact - which allows a human player to choose whether she wants to play against another human player or against the computer. When playing against the computer, the computer should always pick up a random number of beans. Use your function from problem #2 to compute a random number of beans. The human player should be informed of how many beans the computer picked up.

    Choose a reasonable design for your program - create additional subroutines as appropriate.

Handin

Verify that your lab05 folder contains all of the files you created or modified for this lab (which should include PrintStars.java, RollForSum.java, Nim.java, and Nim2.java), then copy your entire lab05 folder to the handin directory ~mcorliss/handin/124/username (where username is replaced with your username).