Skip to content

Simple C# Madlib (Part Three)

Arrays and loops can make our Madlib code more organized.

This is part three in a series to create iterative versions of a Madlib in C#. If you haven't read through Simple C# Madlib (Part One), start there!

Focusing primarily on improving our code, we'll add two arrays and a loop. By using an array we can condense the big block of statements that ask the player to input words. Instead of about thirty lines, we'll have closer to six. Our statements will be more efficient.

We'll also make a dynamic title for the console window's title bar that will be updated with a custom title based on what the player types in.

Arrays

An array is a data structure that can store multiple values. So instead of having ten separate variables for the words we want to replace, we'll have one array that will store the ten values.

string[] Words = {"creature", "luminous", "ghastly", "spectral", "countryman", "farrier", "farmer", "dreadful", "apparition", "hound"};

Array Anatomy

string[] Words = {"creature", "luminous", "ghastly", "spectral", "countryman", "farrier", "farmer", "dreadful", "apparition", "hound"} ;

To create our array we'll first indicate the type of values that will be stored. Next are square brackets indicating this is an array.

Then we have the name of our array (the identifier) "Words".

After the equal sign the curly braces contain the initial list of values, each separated by a comma. Since they are strings, each value is inside of quote marks.

Finally a semicolon terminates the statement.

Alternative Style

You don't have to keep the values on one line. Some programmers prefer to have each element's value on a different line for ease in reading.

Alternative style of writing an array with several values:

string[] Words = {
"creature", 
"luminous", 
"ghastly", 
"spectral", 
"countryman", 
"farrier", 
"farmer", 
"dreadful", 
"apparition", 
"hound"
};

Word Prompts

Our second array will store the prompts for the player (such as asking for a noun or an adjective). Since the two arrays will have their elements synced (i.e., the first element in the Prompt array is the prompt request for the first word in the Words array), we will be able to use the two in tandem to create the equivalent of our previous version's functionality in far fewer lines.

string[] Prompts = { "noun", "adjective", "adjective", "adjective", "occupation", "occupation", "occupation", "adjective", "noun", "noun" };

Accessing Array Elements

To access an item from an array, we use the identifier for the array. In the square brackets we put in the element number of the item in the array we want to use. So for our Words array, we would use the form Words[x], where x would be the number of the element.

string[] Words = {"creature", "luminous", "ghastly", "spectral", "countryman", "farrier", "farmer", "dreadful", "apparition", "hound"};

To access the first word in the Words array ("creature"), we would use: Words[0]. If we wanted to write that first element's value to the console window we could use:

Console.Write("The first element in the Words array is " + Words[0] + ".");

And it would look like this when run:

Madlib array element

When you add the arrays to your code, use the keyword static. Just like in the last part of this series, we won't be making an instance of our Madlib class.

Requesting Player Input

Now that we have our two arrays, we can build a far more efficient way to request input from the player. We'll add a for loop to write out the request for a particular type of word from our Prompts array, and then we'll read in what the player types and store it in our Words array.

If we don't know how many items are in an array, we can use the Length property in our for loop header. This will allow us to cycle through the array without specifying a specific number. It will loop for as many items that are in the array. This is also helpful if we decide later to make the array larger or smaller; there is only one place to update the array size (the loop statement won't need to be updated as well).

When the for loop starts, our counter variable "i" will have a value of zero, so it will print out the first item in the Prompts array (Prompts[0]). When we read in what the player has typed, it will write over the first element in the Words array (Words[0]).

Add your new code to the function/method that handles player input:

//ask player to enter words
for (int i = 0; i < Words.Length; i++)
   {
      Console.Write("Please enter a/an " + Prompts[i] + ": ");
      Words[i] = Console.ReadLine();
   }

Mad Lib prompt


The Madlib array is more efficient
From several lines to six


Updated Title

When we start our Madlib, we can have the window bar show the title of our application.

//Set window bar title
Console.Title = "Make a Madlib";

When we display the finished story, we can update the window bar to have a title that includes words the player entered.

We'll use a string variable (GameTitle) to build up a new title incorporating some of the words entered, then we'll capitalize it so it looks like a title. To capitalize all the letters in a string, we can use the String method ToUpper(). To capitalize just the first letter of words in a title, though, we'll need to add some more code.

  1. Add another using directive to the top of your file: using System.Globalization;
  2. Create a new instance of the CultureInfo* class. In this example, the object is named "TitleCase": TextInfo TitleCase = new CultureInfo("en-US", false).TextInfo;
  3. Set the value of GameTitle to be the value passed through the ToTitleCase method: GameTitle = TitleCase.ToTitleCase(GameTitle);
  4. Update the window title bar: Console.Title = GameTitle;

At the top of your file:

using System.Globalization;

In your function/method that writes out the finished story to the screen:

//Concatenate strings to make a title
GameTitle = "The " + Words[1] + " " + Words[2] + " " + Words[0];

//So we can capitalize the words in our title
TextInfo TitleCase = new CultureInfo("en-US", false).TextInfo;
GameTitle = TitleCase.ToTitleCase(GameTitle);

Console.WriteLine(GameTitle);

//change the title of the application window
Console.Title = GameTitle;

*CultureInfo provides culture-specific information such as the language and country/region. (see MSDN's CultureInfo Class for more information about the class.)

Updating Code: Pulling it all Together

In the last part of this series we reorganized our Madlib code into smaller operations. Integrate the new concepts into your Madlib code: storing words and prompts in arrays, using loops to cycle through them, and creating a custom window bar title.

Below is example code. Your code may be organized differently if you chose to create your own functions/methods in Part Two. If so, just add the code from this part of the series where it makes sense given the way you've set up your file.

Updated Example

using System;
using System.Globalization;

namespace Game
{
    class Madlib
    {
        //declare variables
        static string[] Words = new string[] { "creature", "luminous", "ghastly", "spectral", "countryman", "farrier", "farmer", "dreadful", "apparition", "hound" };
        static string[] Prompts = new string[] { "noun", "adjective", "adjective", "adjective", "occupation", "occupation", "occupation", "adjective", "noun", "noun" };
        static string Story;
        static string GameTitle;

       public static void Run()
        {
            Start();
            GetWords();
            WriteStory();
            End();
        }

        static void Start()
        {
            //Set window bar title
            Console.Title = "Make a Madlib";

            //write header and instructions
            Console.WriteLine("-------");
            Console.WriteLine("Madlib!");
            Console.WriteLine("-------");

        }

        static void GetWords()
        {
            //ask player to enter words
            for (int i = 0; i < Words.Length; i++)
            {
                Console.Write("Please enter a/an " + Prompts[i] + ": ");
                Words[i] = Console.ReadLine();
            }

            //clear the console window
            Console.Clear();
        }


        static void WriteStory()
        {
            //Concatenate strings to make a title
            GameTitle = "The " + Words[1] + " " + Words[2] + " " + Words[0];

            //So we can capitalize the words in our title
            TextInfo TitleCase = new CultureInfo("en-US", false).TextInfo;
            GameTitle = TitleCase.ToTitleCase(GameTitle);

            //Write the title to the console window
            Console.WriteLine(GameTitle);

            //change the title of the application window
            Console.Title = GameTitle;

            //write out story
            Story = "They all agreed that it was a huge {0}, {1}, {2}, and {3}.\nI have cross-examined these men, one of them a hard-headed {4},\none a {5}, and one a moorland {6}, who all tell the same story\nof this {7} {8}, exactly corresponding to the {9} of the legend.";
            Console.WriteLine(Story, Words[0], Words[1], Words[2], Words[3], Words[4], Words[5], Words[6], Words[7], Words[8], Words[9]);

        }
        static void End()
        {
            //keep window open and prompt for exit
            Console.WriteLine("Press enter to exit");
            Console.ReadKey();
        }
    }
    class Program
    {
        static void Main()
        {
            Madlib.Run();
        }
    }
}

Next Steps

Now that you have your Madlib finished, can you improve the interface? Add color and design elements to make the interface more engaging and intuitive.