Multiple Methods

Now that we’ve seen how to write separate methods, we need to learn how to reorganize our main method-only programs to use multiple methods. Here are some general rules for organizing your programs:

  • If you want to repeat the same action more than once, put it in a separate method
  • It’s best when you can see an entire method on the screen without having to scroll. If a method is getting longer than that, consider splitting it up

Suppose we want to write a program that plays a simplified version of Hangman. We will ask the user for a word, and then print out a _ for each letter. We will then repeatedly have the user to guess a letter and then replace each _ with the letter (if it was a correct substitution based on the original word). We will continue this process until the entire word has been guessed.

Here is a main method-only solution to our game:

import java.util.*;
public class Hangman 
{
    public static void main(String[] args) 
    {
        Scanner s = new Scanner(System.in);

        System.out.print("Enter a word: ");
        String word = s.nextLine();

        String result = "";
        for (int i = 0; i < word.length(); i++) 
        {
            result += "_";
        }

        System.out.printf("%nCurrent word: %s%n", result);

        while (!(result.equals(word))) 
        {
            System.out.print("\nGuess a letter: ");
            char letter = (s.nextLine()).charAt(0);

            boolean contains = false;
            for (int i = 0; i < word.length(); i++) 
            {
                if (word.charAt(i) == letter) 
                {
                    contains = true;
                    result = result.substring(0, i) +
                    letter + result.Substring(i+1);
                }
            }

            if (contains == true) 
            {
                System.out.printf("%nCurrent word: %s%n", result);
            }
            else 
            {
                System.out.printf("%n%c is not in the word%n", letter);
            }
        }

        System.out.println("\nYou guessed it!");
    }
}

Here are some separate methods we might consider writing:

  • Building the intial string of “_ _ _ _ _”
  • Guessing a letter, and returning the updated string with that letter substituted in
  • Printing the results after each step

Here is the updated program:

import java.util.*;
public class Hangman 
{
    //s can be seen throughout the file, by all methods
    public static Scanner s;

    public static void main(String[] args) 
    {
        s = new Scanner(System.in);

        System.out.println("Enter a word: ");
        String word = s.nextLine();

        String result = init(word.length());
        System.out.println("\nCurrent word: " + result);

        while (!(result.equals(word))) {
            String update = guessLetter(word, result);

            //result!=update is true if a letter has changed,
            //and false otherwise
            boolean changed = !(result.equals(update));
            printResults(update, letter, changed);
            result = update;
        }
        System.out.println("\nYou guessed it!");
    }

    //returns a string of size ‘_’ characters
    public static String init(int size) 
    {
        String result = "";
        for (int i = 0; i < size; i++) 
        {
            result += "_";
        }

        return result;
    }

    //asks the user for a letter
    //replaces all _ characters in cur when the corresponding
    //character in orig matches the input letter
    //return the updated orig string
    public static string guessLetter(String orig, String cur) 
    {
        System.out.print("\nGuess a letter: ");
        char letter = (s.nextLine()).charAt(0);

        for (int i = 0; i < orig.length(); i++) 
        {
            if (orig.charAt(i) == letter) 
            {
                cur = cur.substring(0, i) + letter + cur.substring(i+1);
            }
        }

        return cur;
    }

    //if update is true, print cur
    //otherwise, print that the most recent letter wasn’t in our word
    public static void printResults(String cur, char letter, boolean update) {
        if (update == true) 
        {
            System.out.printf("%nCurrent word: %s%n", result);
        }
        else 
        {
            System.out.printf("%n%c is not in the word%n", letter);
        }
    }
}

Notice that we can still look at our main method to figure out the flow of the program (the order in which things happen). However, the main method is now a lot easier to read because the details have been passed off to other methods.